wavetermdev/waveterm · error

unsupported API type: %s

Error message

unsupported API type: %s

What it means

GetBackendByAPIType maps an API-type string to a UseChatBackend implementation (openai-responses, openai-completions, anthropic-messages, google-gemini). Any other string returns this error because no backend exists for it.

Source

Thrown at pkg/aiusechat/usechat-backend.go:76

// Compile-time interface checks
var _ UseChatBackend = (*openaiResponsesBackend)(nil)
var _ UseChatBackend = (*openaiCompletionsBackend)(nil)
var _ UseChatBackend = (*anthropicBackend)(nil)
var _ UseChatBackend = (*geminiBackend)(nil)

// GetBackendByAPIType returns the appropriate UseChatBackend implementation for the given API type
func GetBackendByAPIType(apiType string) (UseChatBackend, error) {
	switch apiType {
	case uctypes.APIType_OpenAIResponses:
		return &openaiResponsesBackend{}, nil
	case uctypes.APIType_OpenAIChat:
		return &openaiCompletionsBackend{}, nil
	case uctypes.APIType_AnthropicMessages:
		return &anthropicBackend{}, nil
	case uctypes.APIType_GoogleGemini:
		return &geminiBackend{}, nil
	default:
		return nil, fmt.Errorf("unsupported API type: %s", apiType)
	}
}

// openaiResponsesBackend implements UseChatBackend for OpenAI API
type openaiResponsesBackend struct{}

func (b *openaiResponsesBackend) RunChatStep(
	ctx context.Context,
	sseHandler *sse.SSEHandlerCh,
	chatOpts uctypes.WaveChatOpts,
	cont *uctypes.WaveContinueResponse,
) (*uctypes.WaveStopReason, []uctypes.GenAIMessage, *uctypes.RateLimitInfo, error) {
	stopReason, msgs, rateLimitInfo, err := openai.RunOpenAIChatStep(ctx, sseHandler, chatOpts, cont)
	var genMsgs []uctypes.GenAIMessage
	for _, msg := range msgs {
		genMsgs = append(genMsgs, msg)
	}
	return stopReason, genMsgs, rateLimitInfo, err

View on GitHub (pinned to a4447c1563)

Solutions

  1. Set the API type to one of the supported constants: openai-responses, openai-completions, anthropic-messages, google-gemini (use the uctypes.APIType_* constants)
  2. Check the config/env value for typos, casing, and emptiness before calling
  3. Add a new case in GetBackendByAPIType if you are integrating a new provider backend

Example fix

// before
backend, err := aiusechat.GetBackendByAPIType(apiType) // apiType = "openai"
// after
backend, err := aiusechat.GetBackendByAPIType(uctypes.APIType_OpenAIChat) // "openai-completions"
Defensive patterns

Strategy: validation

Validate before calling

func knownAPIType(t string) bool {
	switch t {
	case uctypes.APIType_OpenAIResponses, uctypes.APIType_OpenAIChat,
		uctypes.APIType_AnthropicMessages, uctypes.APIType_GoogleGemini:
		return true
	}
	return false
}

Type guard

func resolveBackend(t string) (aiusechat.UseChatBackend, error) {
	if !knownAPIType(t) {
		return nil, fmt.Errorf("apitype %q not configured", t)
	}
	return aiusechat.GetBackendByAPIType(t)
}

Try / catch

backend, err := aiusechat.GetBackendByAPIType(cfg.APIType)
if err != nil {
	log.Printf("bad apitype %q: %v; defaulting", cfg.APIType, err)
	backend, err = aiusechat.GetBackendByAPIType(uctypes.APIType_OpenAIResponses)
}
if err != nil { return err }

Prevention

When it happens

Trigger: Calling GetBackendByAPIType with a value not among uctypes.APIType_OpenAIResponses, APIType_OpenAIChat, APIType_AnthropicMessages, APIType_GoogleGemini — e.g. an empty APIType, "openai", "gpt-4", or an arbitrary config string. Raised from callers ConvertAIChatToUIChat, WaveAIPostMessageWrap, and CreateWriteTextFileDiff.

Common situations: Config file with a typo'd or legacy apitype value; env var unset yielding empty string; adding a new provider in code but sending the new type before registering a backend case; case mismatch ("OpenAI" vs the lowercase constant).

Related errors


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