wavetermdev/waveterm · error
message %d: expected *OpenAIChatMessage, got %T
Error message
message %d: expected *OpenAIChatMessage, got %T
What it means
The chat's NativeMessages must all be *OpenAIChatMessage for the OpenAI UI converter; if any element is a different native message type the type assertion fails and this error reports the index and concrete Go type found.
Source
Thrown at pkg/aiusechat/openai/openai-convertmessage.go:559
return nil
}
return &uctypes.UIMessage{
ID: m.MessageId,
Role: role,
Parts: parts,
}
}
// ConvertAIChatToUIChat converts an AIChat to a UIChat for OpenAI
func ConvertAIChatToUIChat(aiChat uctypes.AIChat) (*uctypes.UIChat, error) {
if aiChat.APIType != uctypes.APIType_OpenAIResponses {
return nil, fmt.Errorf("APIType must be '%s', got '%s'", uctypes.APIType_OpenAIResponses, aiChat.APIType)
}
uiMessages := make([]uctypes.UIMessage, 0, len(aiChat.NativeMessages))
for i, nativeMsg := range aiChat.NativeMessages {
openaiMsg, ok := nativeMsg.(*OpenAIChatMessage)
if !ok {
return nil, fmt.Errorf("message %d: expected *OpenAIChatMessage, got %T", i, nativeMsg)
}
uiMsg := openaiMsg.convertToUIMessage()
if uiMsg != nil {
uiMessages = append(uiMessages, *uiMsg)
}
}
return &uctypes.UIChat{
ChatId: aiChat.ChatId,
APIType: aiChat.APIType,
Model: aiChat.Model,
APIVersion: aiChat.APIVersion,
Messages: uiMessages,
}, nil
}
// GetFunctionCallInputByToolCallId returns the OpenAIFunctionCallInput associated with the given ToolCallId,
// or nil if not found in the AIChat
func GetFunctionCallInputByToolCallId(aiChat uctypes.AIChat, toolCallId string) *OpenAIFunctionCallInput {View on GitHub (pinned to a4447c1563)
Solutions
- Ensure all native messages in the chat were produced by the OpenAI Responses backend
- Filter or split messages by type before conversion
- Use the converter matching the actual message type stored in the chat
Example fix
// before
openaiMsg, ok := nativeMsg.(*OpenAIChatMessage) // fails for other types
// after
switch m := nativeMsg.(type) {
case *OpenAIChatMessage:
// handle
default:
return fmt.Errorf("unsupported native message %T", nativeMsg)
} Defensive patterns
Strategy: type-guard
Validate before calling
for i, m := range aiChat.NativeMessages {
if _, ok := m.(*OpenAIChatMessage); !ok {
return fmt.Errorf("message %d not an OpenAIChatMessage", i)
}
} Type guard
func isOpenAIChatMessage(m any) bool { _, ok := m.(*OpenAIChatMessage); return ok } Prevention
- Only append messages from the OpenAI responses backend to these chats
- Type-check native messages after loading persisted history
- Keep one backend per chat history
When it happens
Trigger: aiChat.NativeMessages contains messages produced by another backend (e.g. *anthropic.ChatMessage or *StoredChatMessage) while ConvertAIChatToUIChat expects *OpenAIChatMessage for every entry.
Common situations: Appending native messages from different backends to the same chat; loading mixed persisted history; calling the OpenAI converter on a chat handled by a different backend's RunChatStep (e.g. StoredChatMessage in openaichat).
Related errors
- expected OpenAIChatMessage, got %T
- convertFileAIMessagePart expects 'file' type, got '%s'
- file part missing mimetype
- dropping PDF with URL (must be fetched and converted to base
- PDF file part missing data
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/03c7d5d26c640c51.
Report an issue: GitHub.