wavetermdev/waveterm · error

ai:apitoken is required

Error message

ai:apitoken is required

What it means

buildGeminiHTTPRequest requires an API token to authenticate Gemini requests. 'ai:apitoken is required' is thrown when chatOpts.Config.APIToken is empty, since the library sends the token as the Gemini API key and cannot call the API anonymously. This is an explicit fail-fast check before any network I/O.

Source

Thrown at pkg/aiusechat/gemini/gemini-backend.go:65

	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),
			Temperature:     0.7, // Default temperature
		},
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set the ai:apitoken setting to a valid Google AI Studio API key for the Gemini provider
  2. Confirm the token is configured for the Gemini backend specifically (each provider has its own token field)
  3. Verify config/env loading actually populated opts.APIToken before calling RunGeminiChatStep
  4. Re-check the key after rotating/regenerating it in Google AI Studio and restarting the app

Example fix

// before
chatOpts.Config.APIToken = os.Getenv("") // unset
// after
if chatOpts.Config.APIToken == "" {
    chatOpts.Config.APIToken = os.Getenv("GEMINI_API_KEY")
}
Defensive patterns

Strategy: validation

Validate before calling

if chatOpts.Config.APIToken == "" {
    return fmt.Errorf("Gemini API token not configured; set ai:apitoken or GEMINI_API_KEY")
}

Try / catch

if _, _, _, err := RunGeminiChatStep(ctx, handler, chatOpts, cont); err != nil {
    if err.Error() == "ai:apitoken is required" {
        return fmt.Errorf("missing Gemini API key: configure it in settings")
    }
    return err
}

Prevention

When it happens

Trigger: RunGeminiChatStep is called with chatOpts.Config.APIToken == "": no API key was configured, the key was stored under a different provider's token field, or env/config loading failed silently leaving the token unset.

Common situations: User never obtained a Google AI Studio API key; key was set for OpenAI/Anthropic but not Gemini; the config file was overwritten or a migration dropped the token; running in an environment where the secret store/env var is unavailable.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/22358bb821c1db52. Report an issue: GitHub.