wavetermdev/waveterm · error

ai:endpoint is required

Error message

ai:endpoint is required

What it means

After model and ClientId checks, buildAnthropicHTTPRequest requires an endpoint: opts.Endpoint. Unlike maxTokens, endpoint has no default, so an empty value is a hard error — the library refuses to guess which Anthropic-compatible server to call.

Source

Thrown at pkg/aiusechat/anthropic/anthropic-convertmessage.go:43

)

// 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))
	for i, msg := range msgs {
		convertedMsgs[i] = convertMessageForAPI(msg)
	}

	// inject chatOpts.TabState as a "text" block at the END of the LAST "user" message found (append to Content)
	if chatOpts.TabState != "" {
		// Find the last "user" message
		for i := len(convertedMsgs) - 1; i >= 0; i-- {
			if convertedMsgs[i].Role == "user" {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set chatOpts.Config.Endpoint to the Anthropic API base URL (e.g. "https://api.anthropic.com").
  2. If using a proxy/gateway, set the endpoint to that gateway URL in the ai config.
  3. Validate endpoint presence when loading config so it fails at startup instead of per-request.

Example fix

// before
Config: uctypes.AIConfig{Model: "claude-sonnet-4-20250514"}

// after
Config: uctypes.AIConfig{Model: "claude-sonnet-4-20250514", Endpoint: "https://api.anthropic.com"}
Defensive patterns

Strategy: validation

Validate before calling

if chatOpts.Config.Endpoint == "" {
    chatOpts.Config.Endpoint = "https://api.anthropic.com" // or return an error
}

Type guard

func hasEndpoint(cfg uctypes.AIConfig) bool { return cfg.Endpoint != "" }

Try / catch

_, _, _, err := RunAnthropicChatStep(ctx, sse, chatOpts, cont)
if err != nil && strings.Contains(err.Error(), "ai:endpoint is required") {
    return fmt.Errorf("configure 'ai:endpoint' (e.g. https://api.anthropic.com): %w", err)
}

Prevention

When it happens

Trigger: chatOpts.Config.Endpoint left empty when calling RunAnthropicChatStep; custom proxy setups where the endpoint config key exists but is blank.

Common situations: Users switching from an OpenAI backend (which may default) to Anthropic without adding 'ai:endpoint'; self-hosted gateway config with an empty URL value; config file parsed but the endpoint key misspelled.

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


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