wavetermdev/waveterm · error
ai:model is required
Error message
ai:model is required
What it means
buildAnthropicHTTPRequest requires opts.Model (from chatOpts.Config) because every Anthropic Messages API request must name a model. When Config.Model is empty the request cannot be built, so it fails fast with 'ai:model is required' before any network traffic.
Source
Thrown at pkg/aiusechat/anthropic/anthropic-convertmessage.go:34
"slices"
"strings"
"github.com/google/uuid"
"github.com/wavetermdev/waveterm/pkg/aiusechat/chatstore"
"github.com/wavetermdev/waveterm/pkg/aiusechat/uctypes"
"github.com/wavetermdev/waveterm/pkg/util/logutil"
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
"github.com/wavetermdev/waveterm/pkg/wavebase"
)
// these conversions are based off the anthropic spec
// and the aiprompts/aisdk-uimessage-type.md doc (v5)
// buildAnthropicHTTPRequest creates a complete HTTP request for the Anthropic API
func buildAnthropicHTTPRequest(ctx context.Context, msgs []anthropicInputMessage, chatOpts uctypes.WaveChatOpts) (*http.Request, error) {
opts := chatOpts.Config
if opts.Model == "" {
return nil, errors.New("ai:model is required")
}
if chatOpts.ClientId == "" {
return nil, errors.New("chatOpts.ClientId is required")
}
// Set defaults
endpoint := opts.Endpoint
if endpoint == "" {
return nil, errors.New("ai:endpoint is required")
}
maxTokens := opts.MaxTokens
if maxTokens <= 0 {
maxTokens = AnthropicDefaultMaxTokens
}
// Convert messages to clear FileName fields from Source blocks
convertedMsgs := make([]anthropicInputMessage, len(msgs))View on GitHub (pinned to a4447c1563)
Solutions
- Set chatOpts.Config.Model to a valid Anthropic model id (e.g. "claude-sonnet-4-20250514") before calling.
- If model comes from config, add/fix the 'ai:model' setting in the Wave term/block config and reload.
- Add pre-call validation that surfaces the empty Model at configuration time.
Example fix
// before
chatOpts := uctypes.WaveChatOpts{Config: uctypes.AIConfig{}}
// after
chatOpts := uctypes.WaveChatOpts{Config: uctypes.AIConfig{Model: "claude-sonnet-4-20250514"}} Defensive patterns
Strategy: validation
Validate before calling
if chatOpts.Config.Model == "" {
return fmt.Errorf("config error: ai:model must be set before calling anthropic chat")
} Type guard
func hasModel(cfg uctypes.AIConfig) bool { return cfg.Model != "" } Try / catch
_, _, _, err := RunAnthropicChatStep(ctx, sse, chatOpts, cont)
if err != nil && strings.Contains(err.Error(), "ai:model is required") {
return fmt.Errorf("set 'ai:model' in your term/block config: %w", err)
} Prevention
- Set ai:model in your Wave AI config and verify with a config dump at startup.
- Centralize WaveChatOpts construction in one helper that asserts required fields.
- Keep a list of valid Anthropic model ids in your code/constants.
When it happens
Trigger: Calling RunAnthropicChatStep with chatOpts.Config.Model unset (empty string) — e.g. a WaveChatOpts built from partial config or a preset that never sets Model.
Common situations: Missing 'ai:model' key in user/term config; config loaded from an env or profile that predates the model field; constructing Config{} programmatically in tests; typo'd config key so the model value lands elsewhere.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- chatOpts.ClientId is required
- ai:endpoint is required
- toolResults cannot be empty
- --conn parameter is required
- invalid AIMessage: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/f64348692fdecf3d.
Report an issue: GitHub.