wavetermdev/waveterm · error

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

Error message

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

What it means

RunOpenAIChatStep returns "API version mismatch" at openai-backend.go:487 when chat.APIVersion differs from chatOpts.Config.APIVersion. APIVersion matters for Azure OpenAI–style deployments where the API version string must stay consistent with the stored chat configuration.

Source

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

	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) {
			return nil, nil, nil, fmt.Errorf("cannot continue with a different model, model:%q, cont-model:%q", chatOpts.Config.Model, cont.Model)
		}
	}

	// Convert GenAIMessages to input objects (OpenAIMessage or OpenAIFunctionCallInput)
	var inputs []any

View on GitHub (pinned to a4447c1563)

Solutions

  1. Copy chat.APIVersion into chatOpts.Config.APIVersion before the call
  2. Start a new chat after intentionally changing API version
  3. Ensure all clients/servers use the same configured API version for a given chat
  4. For non-Azure (openai) types, set APIVersion consistently (usually empty) rather than partially filling it

Example fix

// before
chatOpts.Config.APIVersion = "2024-10-21" // newer than chat's stored version
RunOpenAIChatStep(ctx, sse, chatOpts, nil)
// after
chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
chatOpts.Config.APIVersion = chat.APIVersion
RunOpenAIChatStep(ctx, sse, chatOpts, nil)
Defensive patterns

Strategy: validation

Validate before calling

chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
if chat != nil && chat.APIVersion != chatOpts.Config.APIVersion {
    chatOpts.Config.APIVersion = chat.APIVersion
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling RunOpenAIChatStep with Config.APIVersion that differs from the version recorded on the chat — e.g. bumping the Azure API version in config while continuing an existing chat, or defaulting APIVersion to empty vs the stored value.

Common situations: Upgrading the azure-openai api-version in settings; one client process on a newer version continuing a chat created by an older process; leaving Config.APIVersion unset ("") for chats created with an explicit version.

Related errors


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