wavetermdev/waveterm · error

ai:endpoint is required

Error message

ai:endpoint is required

What it means

buildOpenAIHTTPRequest requires a non-empty endpoint to build the OpenAI-compatible HTTP request URL. 'ai:endpoint is required' is thrown when opts.Endpoint is empty after defaults are applied; unlike some OpenAI SDKs there is no implicit fallback to api.openai.com in this code path.

Source

Thrown at pkg/aiusechat/openai/openai-convertmessage.go:212

	// If continuing from premium rate limit, downgrade to default model and medium thinking
	// (medium is more widely supported than low across different models)
	if cont != nil && cont.ContinueFromKind == uctypes.StopKindPremiumRateLimit {
		opts.Model = uctypes.DefaultOpenAIModel
		opts.ThinkingLevel = uctypes.ThinkingLevelMedium
	}

	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 = OpenAIDefaultMaxTokens
	}

	// injected data
	if chatOpts.TabState != "" {
		appendToLastUserMessage(inputs, chatOpts.TabState)
	}
	if chatOpts.PlatformInfo != "" {
		appendToLastUserMessage(inputs, "<PlatformInfo>\n"+chatOpts.PlatformInfo+"\n</PlatformInfo>")
	}
	if chatOpts.AppStaticFiles != "" {
		appendToLastUserMessage(inputs, "<CurrentAppStaticFiles>\n"+chatOpts.AppStaticFiles+"\n</CurrentAppStaticFiles>")
	}
	if chatOpts.AppGoFile != "" {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set ai:endpoint for the OpenAI backend (e.g. https://api.openai.com or your compatible server URL)
  2. If constructing WaveChatOpts in code, assign Config.Endpoint explicitly
  3. For OpenAI-compatible/proxy setups, confirm the endpoint URL scheme and reachability
  4. Default to the standard OpenAI base URL at the call site when Endpoint is empty

Example fix

// before
opts := uctypes.WaveChatOpts{Config: uctypes.WaveChatOptsConfig{Model: "gpt-4o", APIToken: key}}
// after
opts := uctypes.WaveChatOpts{Config: uctypes.WaveChatOptsConfig{Model: "gpt-4o", APIToken: key, Endpoint: "https://api.openai.com"}}
Defensive patterns

Strategy: validation

Validate before calling

if chatOpts.Config.Endpoint == "" {
    chatOpts.Config.Endpoint = "https://api.openai.com"
}

Try / catch

if _, _, _, err := RunOpenAIChatStep(ctx, handler, chatOpts, cont); err != nil {
    if err.Error() == "ai:endpoint is required" {
        chatOpts.Config.Endpoint = "https://api.openai.com"
        return retry()
    }
    return err
}

Prevention

When it happens

Trigger: RunOpenAIChatStep is called where chatOpts.Config.Endpoint == "" and the premium-rate-limit continuation branch did not run (that branch sets Model/ThinkingLevel but the endpoint must still be supplied). Happens when endpoint config is missing for the OpenAI backend or opts are built manually without Endpoint.

Common situations: Fresh install with key and model but no endpoint; switching between OpenAI and OpenAI-compatible providers (e.g. local LLM servers) and forgetting the endpoint; config reset/migration dropping the endpoint; proxy users who removed the custom endpoint.

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-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/efe10c90bbc1b370. Report an issue: GitHub.