wavetermdev/waveterm · error

API type mismatch: chat has %s, chatOpts has %s

Error message

API type mismatch: chat has %s, chatOpts has %s

What it means

RunOpenAIChatStep validates that chatOpts.Config matches the configuration persisted with the chat. "API type mismatch" is returned at openai-backend.go:481 when chat.APIType differs from chatOpts.Config.APIType — the caller is trying to run a chat step with a different provider/API kind (e.g. openai vs azure openai) than the chat was created with.

Source

Thrown at pkg/aiusechat/openai/openai-backend.go:481

func RunOpenAIChatStep(
	ctx context.Context,
	sse *sse.SSEHandlerCh,
	chatOpts uctypes.WaveChatOpts,
	cont *uctypes.WaveContinueResponse,
) (*uctypes.WaveStopReason, []*OpenAIChatMessage, *uctypes.RateLimitInfo, error) {
	if sse == nil {
		return nil, nil, nil, errors.New("sse handler is nil")
	}

	// Get chat from store
	chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
	if chat == nil {
		return nil, nil, nil, fmt.Errorf("chat not found: %s", chatOpts.ChatId)
	}

	// Validate that chatOpts.Config match the chat's stored configuration
	if chat.APIType != chatOpts.Config.APIType {
		return nil, nil, nil, fmt.Errorf("API type mismatch: chat has %s, chatOpts has %s", chat.APIType, chatOpts.Config.APIType)
	}
	if !uctypes.AreModelsCompatible(chat.APIType, chat.Model, chatOpts.Config.Model) {
		return nil, nil, nil, fmt.Errorf("model mismatch: chat has %s, chatOpts has %s", chat.Model, chatOpts.Config.Model)
	}
	if chat.APIVersion != chatOpts.Config.APIVersion {
		return nil, nil, nil, fmt.Errorf("API version mismatch: chat has %s, chatOpts has %s", chat.APIVersion, chatOpts.Config.APIVersion)
	}

	// Context with timeout if provided.
	if chatOpts.Config.TimeoutMs > 0 {
		var cancel context.CancelFunc
		ctx, cancel = context.WithTimeout(ctx, time.Duration(chatOpts.Config.TimeoutMs)*time.Millisecond)
		defer cancel()
	}

	// Validate continuation if provided
	if cont != nil {
		if !uctypes.AreModelsCompatible(chat.APIType, chatOpts.Config.Model, cont.Model) {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Use the chat's stored APIType: read chat.APIType and set chatOpts.Config.APIType accordingly before stepping
  2. Start a new chat with the new API type instead of continuing the existing one
  3. If the provider switch is intentional, migrate/convert the chat history into a chat registered with the new API type
  4. Log both values in the error message when debugging to confirm which side is stale

Example fix

// before
chatOpts.Config.APIType = "openai" // hardcoded
RunOpenAIChatStep(ctx, sse, chatOpts, nil)
// after
chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
chatOpts.Config.APIType = chat.APIType // match stored config
RunOpenAIChatStep(ctx, sse, chatOpts, nil)
Defensive patterns

Strategy: validation

Validate before calling

chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
if chat != nil && chat.APIType != chatOpts.Config.APIType {
    chatOpts.Config.APIType = chat.APIType // or start a new chat
}

Type guard

func apiTypeMatches(chatOpts uctypes.WaveChatOpts) bool {
    chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
    return chat != nil && chat.APIType == chatOpts.Config.APIType
}

Try / catch

if _, _, _, err := RunOpenAIChatStep(ctx, sse, chatOpts, nil); err != nil {
    if strings.HasPrefix(err.Error(), "API type mismatch") {
        // rebuild opts from stored chat config or start a new chat
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Passing chatOpts whose Config.APIType differs from the stored chat's APIType — e.g. reusing a chat id across a provider switch, copying options from another chat, or hardcoding APIType instead of reading it from the chat.

Common situations: User flips the AI provider setting mid-conversation and the client keeps the old ChatId; automation scripts building WaveChatOpts by hand; migrating from OpenAI to Azure OpenAI without starting a new chat.

Related errors


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