{"record":{"id":"a5f2aeff63bcbdf8","repo":"chenhg5/cc-connect","slug":"wecom-ws-sendimage-invalid-reply-context-type-t","errorCode":null,"errorMessage":"wecom-ws: SendImage: invalid reply context type %T","messagePattern":"wecom-ws: SendImage: invalid reply context type %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wecom/websocket_outbound_media.go","lineNumber":25,"sourceCode":"\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/chenhg5/cc-connect/core\"\n)\n\nconst (\n\twecomWSUploadChunkSize = 512 * 1024\n\twecomWSUploadMaxChunks = 100\n)\n\n// SendImage uploads and sends an image through the WeCom AI Bot WebSocket API.\nfunc (p *WSPlatform) SendImage(ctx context.Context, rctx any, img core.ImageAttachment) error {\n\trc, ok := rctx.(wsReplyContext)\n\tif !ok {\n\t\treturn fmt.Errorf(\"wecom-ws: SendImage: invalid reply context type %T\", rctx)\n\t}\n\tif rc.chatID == \"\" {\n\t\treturn fmt.Errorf(\"wecom-ws: chatID is empty, cannot send image\")\n\t}\n\tif len(img.Data) == 0 {\n\t\treturn fmt.Errorf(\"wecom-ws: image data is empty\")\n\t}\n\n\tmediaID, err := p.uploadWSMedia(ctx, \"image\", wsImageFileName(img), img.Data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"wecom-ws: send image: %w\", err)\n\t}\n\tif err := p.sendWSMediaMessage(ctx, rc.chatID, \"image\", mediaID); err != nil {\n\t\treturn fmt.Errorf(\"wecom-ws: send image: %w\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wecom/websocket_outbound_media.go#L7-L43","documentation":"WSPlatform.SendImage requires the reply context argument (rctx) to be the internal wsReplyContext struct, which carries the target chatID for the WeCom AI Bot WebSocket API. This error means the caller passed some other value (nil, a different platform's reply context, or a wrong-typed value), so the platform cannot determine where to send the image. It is a defensive type assertion (`rctx.(wsReplyContext)`) guarding the platform's internal contract.","triggerScenarios":"Calling SendImage with rctx that is not a wecom.wsReplyContext: passing nil, passing a reply context captured from a different platform (e.g. a feishu or telegram context), passing a raw string/int chatID instead of the context struct, or constructing a structurally similar but differently typed value.","commonSituations":"Bridging code that forwards reply contexts across multiple platforms and mixes them up; tests calling SendImage directly with a placeholder context; code refactors where SendText/SendImage were given different context types; using an older reply-context type after a library upgrade changed the internal type.","solutions":["Use the reply context value returned by the same wecom WSPlatform instance (e.g. from its ReceiveMessage/message handling path), never a context from another platform.","If you only have a chatid string, obtain a wsReplyContext via the platform's own APIs rather than synthesizing one; the type is unexported so it must come from the library itself.","Check that you are calling SendImage on the WSPlatform that produced the original inbound message, not on a second platform instance.","In tests, exercise SendImage indirectly through the engine/ReceiveMessage flow so the correct wsReplyContext is produced automatically."],"exampleFix":"// before\nerr := platform.SendImage(ctx, nil, img) // or a foreign reply context\n// after\nerr := platform.SendImage(ctx, wsReplyCtx, img) // wsReplyCtx came from this WSPlatform's message handling","handlingStrategy":"type-guard","validationCode":"if _, ok := rctx.(wecom.WSReplyContextChecker); !ok {\n    return fmt.Errorf(\"cannot send image: reply context is not a wecom WS reply context\")\n}","typeGuard":"func isWSReplyContext(rctx any) bool {\n    if rctx == nil { return false }\n    return fmt.Sprintf(\"%T\", rctx) == \"wecom.wsReplyContext\"\n}","tryCatchPattern":"if err := platform.SendImage(ctx, rctx, img); err != nil {\n    if strings.Contains(err.Error(), \"invalid reply context type\") {\n        // wrong platform/context; skip or re-route\n    }\n}","preventionTips":["Only pass reply contexts obtained from the same WSPlatform instance's message handling path.","Never share reply contexts across platform adapters.","Exercise media sends through the engine flow in tests rather than calling SendImage with synthetic contexts.","Check the %T in the error message to identify exactly which type was passed."],"tags":["go","type-assertion","wecom","reply-context"],"backgroundTag":"invalid-argument-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"}