Error Types
Error types returned by Go AI SDK functions.
Typed Errors
Many SDK functions return specific error types instead of (or in addition to)
plain errors.New/fmt.Errorf values. Use errors.As to detect them. Most
live in pkg/ai; a few tool/provider-level ones live in pkg/provider/types
and pkg/provider.
| Type | Package | Key Fields | When it's returned |
|---|---|---|---|
NoSuchToolError | ai | ToolName, AvailableTools | Model called a tool that isn't available |
InvalidToolInputError | ai | ToolName, ToolInput, Cause | Tool input doesn't satisfy the tool's schema |
ToolCallRepairError | ai | Cause, OriginalError | RepairToolCall failed to fix a bad tool call |
ToolChoiceViolationError | ai | ToolChoice, FinishReason, Provider, ModelID | Response didn't honor a required/specific ToolChoice |
ToolCallNotFoundForApprovalError | ai | ToolCallID, ApprovalID | Approval references a tool call missing from history |
InvalidToolApprovalError | ai | ApprovalID | Approval response has no matching request |
InvalidToolApprovalSignatureError | ai | ApprovalID, ToolCallID, Reason | Signed approval could not be verified |
NoObjectGeneratedError | ai | Message, Cause, Text, Response, Usage, FinishReason | GenerateObject/StreamObject produced no valid object |
NoOutputGeneratedError | ai | Message, Cause | Stream ended before any output or finish chunk |
NoImageGeneratedError | ai | Responses, Calls | GenerateImage produced zero images |
NoSpeechGeneratedError | ai | Responses | GenerateSpeech produced no audio |
NoVideoGeneratedError | ai | Responses | GenerateVideo produced no videos |
NoTranscriptGeneratedError | ai | Responses | Transcribe produced no text |
NoTranslationGeneratedError | ai | Response | Speech translation produced no audio or text |
MessageConversionError | ai | OriginalMessage, Message, Cause | A UI message couldn't convert to a model message |
TimeoutError | ai | Reason, Err | A configured TimeoutConfig deadline was hit |
UIMessageStreamError | ai | ChunkType, ChunkID, Message | A UI message stream received an out-of-sequence chunk |
types.MissingToolResultError | provider/types | ToolCallID, ToolName, Message | A provider-executed tool didn't return a result |
types.MissingToolResultsError | provider/types | ToolCallIDs, Message | Multiple provider-executed tools are missing results |
types.ToolExecutionError | provider/types | ToolCallID, ToolName, Err, ProviderExecuted | A tool's Execute function returned an error |
provider.BatchError | provider | Message, Type, Code, StatusCode | Serializable error info for a failed batch item |
provider.NoSuchUploadAPIError | provider | API | Provider has no upload API of the requested kind |
The SDK also exposes Is*Error(err) bool helper functions for most of the
types above as an alternative to errors.As, for example
ai.IsNoSuchToolError, ai.IsInvalidToolInputError,
ai.IsToolChoiceViolationError, ai.IsNoImageGeneratedError,
ai.IsNoOutputGeneratedError, and ai.IsMessageConversionError.
NoObjectGeneratedError and TimeoutError have no Is* helper; use
errors.As for those.
Example: errors.As
package main
import (
"context"
"errors"
"fmt"
"log"
"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/provider/types"
"github.com/digitallysavvy/go-ai/pkg/providers/openai"
)
func main() {
p := openai.New(openai.Config{APIKey: "your-api-key"})
model, _ := p.LanguageModel("gpt-4")
weatherTool := types.Tool{Name: "get_weather"}
result, err := ai.GenerateText(context.Background(), ai.GenerateTextOptions{
Model: model,
Prompt: "Use the weather tool",
Tools: []types.Tool{weatherTool},
StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
})
if err != nil {
var noSuchTool *ai.NoSuchToolError
var invalidInput *ai.InvalidToolInputError
switch {
case errors.As(err, &noSuchTool):
log.Printf("model tried calling unknown tool %q", noSuchTool.ToolName)
case errors.As(err, &invalidInput):
log.Printf("tool %q got invalid input: %v", invalidInput.ToolName, invalidInput.Cause)
default:
log.Fatal(err)
}
return
}
fmt.Println(result.Text)
}
Untyped Errors
Many lower-level validation and provider failures are still plain Go errors with descriptive messages rather than a dedicated type, for example:
"model is required"
"prompt is required"
provider-specific HTTP errors wrapped from the provider's API response
Check these with strings.Contains(err.Error(), "...") as shown below, or
prefer the typed errors above and ai.Is*Error helpers where one exists.
Error Handling Patterns
Basic Error Handling
package main
import (
"context"
"log"
"github.com/digitallysavvy/go-ai/pkg/ai"
"github.com/digitallysavvy/go-ai/pkg/providers/openai"
)
func main() {
p := openai.New(openai.Config{APIKey: "your-api-key"})
model, _ := p.LanguageModel("gpt-4")
opts := ai.GenerateTextOptions{Model: model, Prompt: "Hello"}
result, err := ai.GenerateText(context.Background(), opts)
if err != nil {
log.Fatal(err)
}
log.Println(result.Text)
}
Timeout Errors
result, err := ai.GenerateText(ctx, opts)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
log.Println("Request timed out")
return
}
log.Fatal(err)
}
Cancellation Errors
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(5 * time.Second)
cancel()
}()
result, err := ai.GenerateText(ctx, opts)
if err != nil {
if errors.Is(err, context.Canceled) {
log.Println("Request was canceled")
return
}
log.Fatal(err)
}
Validation Errors
result, err := ai.GenerateText(ctx, opts)
if err != nil {
switch {
case strings.Contains(err.Error(), "model is required"):
log.Println("Must provide a model")
case strings.Contains(err.Error(), "prompt is required"):
log.Println("Must provide a prompt or messages")
default:
log.Println("Unknown validation error:", err)
}
return
}
Provider-Specific Errors
result, err := ai.GenerateText(ctx, opts)
if err != nil {
switch {
case strings.Contains(err.Error(), "API key"):
log.Println("Invalid or missing API key")
case strings.Contains(err.Error(), "rate limit"):
log.Println("Rate limited - retry later")
time.Sleep(time.Minute)
// Retry logic
case strings.Contains(err.Error(), "content policy"):
log.Println("Content policy violation")
case strings.Contains(err.Error(), "invalid model"):
log.Println("Model not found or not supported")
default:
log.Println("Provider error:", err)
}
return
}
Retry Logic
func generateWithRetry(ctx context.Context, opts ai.GenerateTextOptions, maxRetries int) (*ai.GenerateTextResult, error) {
var result *ai.GenerateTextResult
var err error
for attempt := 0; attempt < maxRetries; attempt++ {
result, err = ai.GenerateText(ctx, opts)
if err == nil {
return result, nil
}
// Check if error is retryable
if strings.Contains(err.Error(), "rate limit") {
waitTime := time.Duration(attempt+1) * time.Second
log.Printf("Rate limited, retrying in %v (attempt %d/%d)",
waitTime, attempt+1, maxRetries)
time.Sleep(waitTime)
continue
}
// Non-retryable error
return nil, err
}
return nil, fmt.Errorf("max retries exceeded: %w", err)
}
Tool Execution Errors
weatherTool := types.Tool{
Name: "get_weather",
Description: "Get weather",
Parameters: weatherSchema,
Execute: func(ctx context.Context, input map[string]interface{}, opts types.ToolExecutionOptions) (interface{}, error) {
location, ok := input["location"].(string)
if !ok {
return nil, fmt.Errorf("location must be a string")
}
weather, err := fetchWeather(location)
if err != nil {
return nil, fmt.Errorf("failed to fetch weather: %w", err)
}
return weather, nil
},
}
result, err := ai.GenerateText(ctx, ai.GenerateTextOptions{
Model: model,
Prompt: "What's the weather?",
Tools: []types.Tool{weatherTool},
StopWhen: []ai.StopCondition{ai.IsStepCount(5)},
})
if err != nil {
if strings.Contains(err.Error(), "tool execution failed") {
log.Println("A tool failed during execution:", err)
}
}
Stream Errors
result, err := ai.StreamText(ctx, opts)
if err != nil {
log.Fatal("Failed to start stream:", err)
}
defer result.Close()
for {
chunk, err := result.Stream().Next()
if err == io.EOF {
break
}
if err != nil {
log.Printf("Stream error: %v", err)
break
}
// Process chunk
}
// Check for accumulated errors
if result.Err() != nil {
log.Printf("Stream had errors: %v", result.Err())
}
Schema Validation Errors
result, err := ai.GenerateObject(ctx, ai.GenerateObjectOptions{
Model: model,
Prompt: "Generate user data",
Schema: schema,
})
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
log.Println("Generated object doesn't match schema:", err)
}
return
}
See Also
- GenerateText - Text generation
- Usage Types - Token usage tracking
- Tool Types - Tool-related types