{"record":{"id":"03c7d5d26c640c51","repo":"wavetermdev/waveterm","slug":"message-d-expected-openaichatmessage-got-t","errorCode":null,"errorMessage":"message %d: expected *OpenAIChatMessage, got %T","messagePattern":"message (.+?): expected \\*OpenAIChatMessage, got %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/openai/openai-convertmessage.go","lineNumber":559,"sourceCode":"\t\treturn nil\n\t}\n\treturn &uctypes.UIMessage{\n\t\tID:    m.MessageId,\n\t\tRole:  role,\n\t\tParts: parts,\n\t}\n}\n\n// ConvertAIChatToUIChat converts an AIChat to a UIChat for OpenAI\nfunc ConvertAIChatToUIChat(aiChat uctypes.AIChat) (*uctypes.UIChat, error) {\n\tif aiChat.APIType != uctypes.APIType_OpenAIResponses {\n\t\treturn nil, fmt.Errorf(\"APIType must be '%s', got '%s'\", uctypes.APIType_OpenAIResponses, aiChat.APIType)\n\t}\n\tuiMessages := make([]uctypes.UIMessage, 0, len(aiChat.NativeMessages))\n\tfor i, nativeMsg := range aiChat.NativeMessages {\n\t\topenaiMsg, ok := nativeMsg.(*OpenAIChatMessage)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"message %d: expected *OpenAIChatMessage, got %T\", i, nativeMsg)\n\t\t}\n\t\tuiMsg := openaiMsg.convertToUIMessage()\n\t\tif uiMsg != nil {\n\t\t\tuiMessages = append(uiMessages, *uiMsg)\n\t\t}\n\t}\n\treturn &uctypes.UIChat{\n\t\tChatId:     aiChat.ChatId,\n\t\tAPIType:    aiChat.APIType,\n\t\tModel:      aiChat.Model,\n\t\tAPIVersion: aiChat.APIVersion,\n\t\tMessages:   uiMessages,\n\t}, nil\n}\n\n// GetFunctionCallInputByToolCallId returns the OpenAIFunctionCallInput associated with the given ToolCallId,\n// or nil if not found in the AIChat\nfunc GetFunctionCallInputByToolCallId(aiChat uctypes.AIChat, toolCallId string) *OpenAIFunctionCallInput {","sourceCodeStart":541,"sourceCodeEnd":577,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/openai/openai-convertmessage.go#L541-L577","documentation":"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.","triggerScenarios":"aiChat.NativeMessages contains messages produced by another backend (e.g. *anthropic.ChatMessage or *StoredChatMessage) while ConvertAIChatToUIChat expects *OpenAIChatMessage for every entry.","commonSituations":"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).","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"],"exampleFix":"// before\nopenaiMsg, ok := nativeMsg.(*OpenAIChatMessage) // fails for other types\n// after\nswitch m := nativeMsg.(type) {\ncase *OpenAIChatMessage:\n    // handle\ndefault:\n    return fmt.Errorf(\"unsupported native message %T\", nativeMsg)\n}","handlingStrategy":"type-guard","validationCode":"for i, m := range aiChat.NativeMessages {\n    if _, ok := m.(*OpenAIChatMessage); !ok {\n        return fmt.Errorf(\"message %d not an OpenAIChatMessage\", i)\n    }\n}","typeGuard":"func isOpenAIChatMessage(m any) bool { _, ok := m.(*OpenAIChatMessage); return ok }","tryCatchPattern":null,"preventionTips":["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"],"tags":["type-assertion","openai","message-conversion"],"backgroundTag":"unexpected-message-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}