{"record":{"id":"6ad4f305a649d9cd","repo":"chenhg5/cc-connect","slug":"qqbot-unknown-message-type-q","errorCode":null,"errorMessage":"qqbot: unknown message type %q","messagePattern":"qqbot: unknown message type %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/qqbot/qqbot.go","lineNumber":253,"sourceCode":"func (p *Platform) SendImage(ctx context.Context, replyCtx any, img core.ImageAttachment) error {\n\trctx, ok := replyCtx.(*replyContext)\n\tif !ok {\n\t\treturn fmt.Errorf(\"qqbot: SendImage: invalid reply context type %T\", replyCtx)\n\t}\n\n\tfileInfo, err := p.uploadRichMedia(rctx, 1, img.Data, \"\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"qqbot: upload image: %w\", err)\n\t}\n\n\tvar url string\n\tswitch rctx.messageType {\n\tcase \"group\":\n\t\turl = fmt.Sprintf(\"%s/v2/groups/%s/messages\", p.apiBase(), rctx.groupOpenID)\n\tcase \"c2c\":\n\t\turl = fmt.Sprintf(\"%s/v2/users/%s/messages\", p.apiBase(), rctx.userOpenID)\n\tdefault:\n\t\treturn fmt.Errorf(\"qqbot: unknown message type %q\", rctx.messageType)\n\t}\n\n\tbody := map[string]any{\n\t\t\"msg_type\": 7,\n\t\t\"media\":    map[string]any{\"file_info\": fileInfo},\n\t}\n\tif rctx.eventMsgID != \"\" {\n\t\tbody[\"msg_id\"] = rctx.eventMsgID\n\t\tbody[\"msg_seq\"] = p.nextMsgSeq(rctx.eventMsgID)\n\t}\n\n\treturn p.apiRequest(\"POST\", url, body)\n}\n\n// uploadRichMedia uploads a file to QQ Bot rich media API and returns the file_info.\n// fileType: 1=image, 2=video, 3=audio, 4=file.\nfunc (p *Platform) uploadRichMedia(rctx *replyContext, fileType int, data []byte, fileName string) (string, error) {\n\tvar url string","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/qqbot/qqbot.go#L235-L271","documentation":"SendImage() switches on rctx.messageType, which can only be \"group\" or \"c2c\" for a well-formed reply context; anything else hits the default branch and returns this error. It signals an internally inconsistent or corrupted reply context rather than a caller-visible input problem.","triggerScenarios":"A *replyContext whose messageType field was set to an unexpected value (future message types like channel/guild not yet handled, or a manually constructed context).","commonSituations":"Upgrading the library after QQ added new message types while running an older adapter that never learned the new type string; hand-crafted contexts in tests; concurrency bugs that overwrite messageType.","solutions":["Upgrade the qqbot package to a version that supports the message type in your context.","Check where the *replyContext was created — it should only come from the platform's own receive path.","Log the full reply context (groupOpenID/userOpenID/messageType) to identify how it was corrupted.","Handle channel-type messages via a different code path if the platform does not map them to group/c2c sends."],"exampleFix":"// before\n// replyContext built by hand:\nrctx := &replyContext{messageType: \"guild\", groupOpenID: id}\nerr := p.SendImage(ctx, rctx, img) // unknown message type \"guild\"\n// after\nrctx := msg.ReplyContext() // platform-issued, messageType is \"group\" or \"c2c\"\nerr := p.SendImage(ctx, rctx, img)","handlingStrategy":"validation","validationCode":"if rc.messageType != \"group\" && rc.messageType != \"c2c\" {\n    return fmt.Errorf(\"unsupported messageType %q for image send\", rc.messageType)\n}","typeGuard":"func sendableReplyContext(rc *replyContext) bool {\n    return rc.messageType == \"group\" || rc.messageType == \"c2c\"\n}","tryCatchPattern":"if err := p.SendImage(ctx, replyCtx, img); err != nil {\n    if strings.Contains(err.Error(), \"unknown message type\") {\n        // upgrade adapter or route channel-type messages elsewhere\n    }\n}","preventionTips":["Only build reply contexts inside the platform's receive path.","Keep the adapter updated for new QQ message types (guild/channel).","Assert messageType right after constructing/receiving the context.","Cover both group and c2c paths in tests, plus a negative case."],"tags":["qqbot","enum","reply-context"],"backgroundTag":"invalid-enum-value","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}