{"record":{"id":"886f26daae999e7b","repo":"wavetermdev/waveterm","slug":"apitype-must-be-s-got-s-886f26","errorCode":null,"errorMessage":"APIType must be '%s', got '%s'","messagePattern":"APIType must be '(.+?)', got '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/openai/openai-convertmessage.go","lineNumber":553,"sourceCode":"\t\t}\n\t} else if m.FunctionCallOutput != nil {\n\t\t// FunctionCallOutput messages are not converted to UIMessage\n\t\treturn nil\n\t}\n\tif len(parts) == 0 {\n\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,","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/openai/openai-convertmessage.go#L535-L571","documentation":"ConvertAIChatToUIChat only accepts AIChats whose APIType is APIType_OpenAIResponses; passing a chat created for a different backend (e.g. anthropic or openai-completions) fails this guard, reporting the expected and actual APIType.","triggerScenarios":"Calling ConvertAIChatToUIChat on an AIChat built/loaded with aiChat.APIType set to anything other than uctypes.APIType_OpenAIResponses.","commonSituations":"Mixing backends after switching providers; loading a persisted chat that was created with a different API type; wiring the OpenAI UI converter to a chat produced by the Anthropic backend.","solutions":["Check aiChat.APIType before converting and route to the matching backend's ConvertAIChatToUIChat","Re-create the chat with the OpenAI Responses backend if it was misconfigured","Verify persisted chat metadata (APIType) was not corrupted or defaulted incorrectly"],"exampleFix":"// before\nui, err := openai.ConvertAIChatToUIChat(aiChat) // APIType is anthropic\n// after\nif aiChat.APIType != uctypes.APIType_OpenAIResponses {\n    return fmt.Errorf(\"unsupported APIType %q for openai converter\", aiChat.APIType)\n}\nui, err := openai.ConvertAIChatToUIChat(aiChat)","handlingStrategy":"validation","validationCode":"if aiChat.APIType != uctypes.APIType_OpenAIResponses {\n    return fmt.Errorf(\"need %s chat, got %s\", uctypes.APIType_OpenAIResponses, aiChat.APIType)\n}","typeGuard":"func isOpenAIResponsesChat(c uctypes.AIChat) bool { return c.APIType == uctypes.APIType_OpenAIResponses }","tryCatchPattern":null,"preventionTips":["Route chats to converters by APIType via a switch/map","Preserve APIType in persisted chat metadata","Don't mix backends in one chat object"],"tags":["openai","api-type","validation"],"backgroundTag":"incompatible-api-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}