{"record":{"id":"21015685296c2ad8","repo":"chenhg5/cc-connect","slug":"wecom-sendimage-invalid-reply-context-type-t","errorCode":null,"errorMessage":"wecom: SendImage: invalid reply context type %T","messagePattern":"wecom: SendImage: invalid reply context type %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wecom/wecom.go","lineNumber":498,"sourceCode":"\t\t\tslog.Error(\"wecom: send failed\", \"user\", rc.userID, \"chunk\", i, \"error\", sendErr)\n\t\t\treturn sendErr\n\t\t}\n\t}\n\tslog.Debug(\"wecom: message sent\", \"user\", rc.userID, \"chunks\", len(chunks), \"total_len\", len(content))\n\treturn nil\n}\n\n// Send sends a new message (same as Reply for WeChat Work)\nfunc (p *Platform) Send(ctx context.Context, rctx any, content string) error {\n\treturn p.Reply(ctx, rctx, content)\n}\n\n// SendImage uploads and sends an image to the user.\n// Implements core.ImageSender.\nfunc (p *Platform) SendImage(ctx context.Context, rctx any, img core.ImageAttachment) error {\n\trc, ok := rctx.(replyContext)\n\tif !ok {\n\t\treturn fmt.Errorf(\"wecom: SendImage: invalid reply context type %T\", rctx)\n\t}\n\n\taccessToken, err := p.getAccessToken()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wecom: send image: %w\", err)\n\t}\n\n\tmediaID, err := p.uploadImageMedia(accessToken, img)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wecom: send image: %w\", err)\n\t}\n\n\tpayload := map[string]any{\n\t\t\"touser\":  rc.userID,\n\t\t\"msgtype\": \"image\",\n\t\t\"agentid\": p.agentID,\n\t\t\"image\":   map[string]string{\"media_id\": mediaID},\n\t}","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wecom/wecom.go#L480-L516","documentation":"SendImage() implements core.ImageSender and, like Reply, requires the rctx parameter to be the wecom platform's internal replyContext struct. Any other value fails the type assertion and returns this error, which embeds the offending type for diagnosis.","triggerScenarios":"Calling SendImage with nil, a plain string user ID, a *replyContext pointer instead of the value type (or vice versa), or a reply context from a different platform adapter.","commonSituations":"Generic image-forwarding middleware written against multiple platforms that passes its own context struct; refactor changing replyContext between value and pointer types; cross-wiring platform adapters.","solutions":["Pass the replyContext value produced by this platform's inbound message handling","Ensure the exact type matches (value type replyContext, not a pointer or copy in another package)","Route image sends through the engine rather than calling platform methods with hand-made contexts"],"exampleFix":"// before\nerr := p.SendImage(ctx, &rc, img) // pointer vs value type mismatch\n// after\nerr := p.SendImage(ctx, rc, img) // replyContext value from the inbound message","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"rc, ok := rctx.(replyContext)\nif !ok {\n\treturn fmt.Errorf(\"cannot send image: expected wecom replyContext, got %T\", rctx)\n}","tryCatchPattern":null,"preventionTips":["Pass only reply contexts obtained from this platform's message flow","Keep middleware platform-agnostic so it forwards contexts unchanged","Guard against value-vs-pointer drift when refactoring replyContext"],"tags":["wecom","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"}