{"record":{"id":"09e71c7df2f49add","repo":"chenhg5/cc-connect","slug":"max-unexpected-replyctx-type-t","errorCode":null,"errorMessage":"max: unexpected replyCtx type %T","messagePattern":"max: unexpected replyCtx type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/max/max.go","lineNumber":420,"sourceCode":"\tfor _, row := range buttons {\n\t\tmaxRow := make([]maxButton, 0, len(row))\n\t\tfor _, btn := range row {\n\t\t\tmaxRow = append(maxRow, maxButton{\n\t\t\t\tType:    \"callback\",\n\t\t\t\tText:    btn.Text,\n\t\t\t\tPayload: btn.Data,\n\t\t\t})\n\t\t}\n\t\tmaxButtons = append(maxButtons, maxRow)\n\t}\n\treturn p.sendText(ctx, replyCtx, content, maxButtons)\n}\n\n// SendImage implements core.ImageSender.\nfunc (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(\"max: unexpected replyCtx type %T\", replyCtx)\n\t}\n\ttoken, err := p.uploadAttachment(ctx, \"image\", img.Data, img.FileName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"max: upload image: %w\", err)\n\t}\n\tbody := &maxSendBody{\n\t\tAttachments: []maxOutAttachment{{\n\t\t\tType:    \"image\",\n\t\t\tPayload: maxTokenPayload{Token: token},\n\t\t}},\n\t}\n\treturn p.postMessage(ctx, rctx.chatID, body)\n}\n\n// SendFile implements core.FileSender. MAX routes images uploaded via the file\n// endpoint as type=\"file\" in the message, so we honor the declared kind: if the\n// mime says image/*, we upload as image so the recipient sees a proper image\n// preview instead of a generic file card.","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/max/max.go#L402-L438","documentation":"SendImage implements core.ImageSender and expects replyCtx to be the platform's internal replyContext type (obtained from messages handled by this platform). Passing any other value returns this type-mismatch error.","triggerScenarios":"Calling SendImage with a replyCtx produced by a different platform, a manually constructed value, or a stale/generic reply context (e.g. nil or a string).","commonSituations":"Routing reply contexts across platform adapters in a multi-platform setup; persisting replyCtx in a session store and reloading it as the wrong type.","solutions":["Only pass the replyCtx that this MAX platform itself handed to your handler.","Verify replyCtx is max's replyContext via a type assertion before calling SendImage.","Ensure session storage serializes/deserializes the context without changing its type."],"exampleFix":"// before\np.SendImage(ctx, someOtherPlatformCtx, img)\n// after\nif _, ok := someCtx.(replyContext); ok { p.SendImage(ctx, someCtx, img) }","handlingStrategy":"type-guard","validationCode":"if _, ok := replyCtx.(replyContext); !ok { return errors.New(\"replyCtx is not a max replyContext\") }","typeGuard":"func isMaxReplyCtx(v any) bool { _, ok := v.(replyContext); return ok }","tryCatchPattern":"if err := p.SendImage(ctx, replyCtx, img); err != nil {\n    if strings.Contains(err.Error(), \"unexpected replyCtx type\") {\n        // wrong adapter's context: route to the correct platform\n    }\n}","preventionTips":["Only pass replyCtx values received from this platform's own message handler","Never persist reply contexts in a way that loses their concrete type","Tag stored contexts with the platform name and check before use"],"tags":["go","type-mismatch","api-misuse"],"backgroundTag":"type-mismatch","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"}