wavetermdev/waveterm · error
model mismatch: chat has %s, chatOpts has %s
Error message
model mismatch: chat has %s, chatOpts has %s
What it means
RunOpenAIChatStep checks model compatibility with uctypes.AreModelsCompatible(chat.APIType, chat.Model, chatOpts.Config.Model) and returns "model mismatch" at openai-backend.go:484 when the chat's stored model is incompatible with the model in the request options. This prevents mixing history generated by one model into a request for an incompatible model.
Source
Thrown at pkg/aiusechat/openai/openai-backend.go:484
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) {
return nil, nil, nil, fmt.Errorf("cannot continue with a different model, model:%q, cont-model:%q", chatOpts.Config.Model, cont.Model)
}
}View on GitHub (pinned to a4447c1563)
Solutions
- Set chatOpts.Config.Model from the chat's stored model (chat.Model) before stepping
- Start a new chat when intentionally switching to a different model
- Check uctypes.AreModelsCompatible to see whether the two models are considered compatible aliases (e.g. versioned variants) before assuming mismatch
- If the model was deprecated, migrate the chat to the new compatible model name once, or recreate the chat
Example fix
// before chatOpts.Config.Model = "gpt-4.1" // switched mid-chat RunOpenAIChatStep(ctx, sse, chatOpts, nil) // after chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId) chatOpts.Config.Model = chat.Model // continue with the chat's model RunOpenAIChatStep(ctx, sse, chatOpts, nil)
Defensive patterns
Strategy: validation
Validate before calling
chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
if chat != nil && !uctypes.AreModelsCompatible(chat.APIType, chat.Model, chatOpts.Config.Model) {
chatOpts.Config.Model = chat.Model // or start a new chat with the new model
} Type guard
func modelCompatible(chatOpts uctypes.WaveChatOpts) bool {
chat := chatstore.DefaultChatStore.Get(chatOpts.ChatId)
return chat != nil && uctypes.AreModelsCompatible(chat.APIType, chat.Model, chatOpts.Config.Model)
} Try / catch
if _, _, _, err := RunOpenAIChatStep(ctx, sse, chatOpts, nil); err != nil {
if strings.HasPrefix(err.Error(), "model mismatch") {
// either reset Config.Model to the chat's model or create a new chat
return nil
}
return err
} Prevention
- Read the model from the chat record for continuation steps
- Check AreModelsCompatible before switching model strings (aliases count)
- Start a fresh chat on intentional model change
- Watch for deprecated model names after upstream upgrades
When it happens
Trigger: Calling RunOpenAIChatStep with Config.Model different (and not compatible per AreModelsCompatible) from the model the chat was created with — e.g. user switches model mid-conversation, or opts built from defaults rather than the chat record.
Common situations: Model upgraded/renamed server-side so old chats carry a retired model name; user changes model selection in the UI while continuing a conversation; config file defaults overriding the chat's model.
Related errors
- API type mismatch: chat has %s, chatOpts has %s
- cannot continue with a different model, model:%q, cont-model
- ai:model is required
- ai:endpoint is required
- wcloud endpoint not set
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/b090a3c3ff18d0b6.
Report an issue: GitHub.