wavetermdev/waveterm · error
ai:model is required
Error message
ai:model is required
What it means
buildGeminiHTTPRequest validates the WaveChatOpts.Config before constructing the Gemini API request. The 'ai:model is required' error is thrown when opts.Model is empty because the Gemini API needs an explicit model name to build the request URL and payload. The library does not apply a default model for Gemini.
Source
Thrown at pkg/aiusechat/gemini/gemini-backend.go:62
// appendPartToLastUserMessage appends a text part to the last user message in the contents slice
func appendPartToLastUserMessage(contents []GeminiContent, text string) {
for i := len(contents) - 1; i >= 0; i-- {
if contents[i].Role == "user" {
contents[i].Parts = append(contents[i].Parts, GeminiMessagePart{
Text: text,
})
break
}
}
}
// buildGeminiHTTPRequest creates an HTTP request for the Gemini API
func buildGeminiHTTPRequest(ctx context.Context, contents []GeminiContent, chatOpts uctypes.WaveChatOpts) (*http.Request, error) {
opts := chatOpts.Config
if opts.Model == "" {
return nil, errors.New("ai:model is required")
}
if opts.APIToken == "" {
return nil, errors.New("ai:apitoken is required")
}
if opts.Endpoint == "" {
return nil, errors.New("ai:endpoint is required")
}
maxTokens := opts.MaxTokens
if maxTokens <= 0 {
maxTokens = GeminiDefaultMaxTokens
}
// Build request body
reqBody := &GeminiRequest{
Contents: contents,
GenerationConfig: &GeminiGenerationConfig{
MaxOutputTokens: int32(maxTokens),View on GitHub (pinned to a4447c1563)
Solutions
- Set the ai:model setting (e.g. in Wave's AI config) to a valid Gemini model such as gemini-2.0-flash or gemini-1.5-pro
- If using per-provider config, ensure the model is set under the Gemini provider block, not another backend's
- Reload/restart the app after editing config so the new model value is picked up
- Add pre-flight validation in the calling code to surface a friendlier message when opts.Model is empty
Example fix
// before
chatOpts.Config.Model = ""
RunGeminiChatStep(ctx, sseHandler, chatOpts, cont)
// after
if chatOpts.Config.Model == "" {
chatOpts.Config.Model = "gemini-2.0-flash"
}
RunGeminiChatStep(ctx, sseHandler, chatOpts, cont) Defensive patterns
Strategy: validation
Validate before calling
if err := validateGeminiConfig(chatOpts.Config); err != nil {
return err
} Try / catch
if _, _, _, err := RunGeminiChatStep(ctx, handler, chatOpts, cont); err != nil {
if err.Error() == "ai:model is required" {
// surface config UI or apply default model
chatOpts.Config.Model = "gemini-2.0-flash"
return retry()
}
return err
} Prevention
- Configure ai:model before selecting the Gemini backend
- Keep per-provider config sections distinct so a model set for OpenAI is not mistaken for a Gemini model
- Validate the full config (model, token, endpoint) at startup and surface gaps to the user
When it happens
Trigger: RunGeminiChatStep is invoked with chatOpts.Config.Model == "" — e.g. the user's settings never specified ai:model, the model was cleared in config, or the Gemini backend was selected without a per-backend model override.
Common situations: Fresh install where only the API token was configured; switching from another provider (OpenAI/Anthropic) that has its own default model to Gemini; a config migration or typo'd key (model defined under the wrong backend section) leaving the Gemini model empty.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- ai:apitoken is required
- ai:endpoint is required
- ai:model is required
- No tab view found for the given webContents id
- cannot call ${methodName}: no web endpoint
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/a77b7c7635fff6c0.
Report an issue: GitHub.