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
- Set chatOpts.Config.Endpoint to the Anthropic API base URL (e.g. "https://api.anthropic.com").
- If using a proxy/gateway, set the endpoint to that gateway URL in the ai config.
- 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
- Set ai:endpoint whenever you configure an Anthropic backend, including proxy setups.
- Apply a default endpoint in a config-normalization step so it is never empty.
- Recheck endpoint config after switching backends between providers.
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
- cannot call ${methodName}: no web endpoint
- ai:model is required
- chatOpts.ClientId is required
- wcloud endpoint not set
- wcloud ping endpoint not set
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/72878d4db877bb4f.
Report an issue: GitHub.