{"record":{"id":"5c4200850b222ac8","repo":"chenhg5/cc-connect","slug":"dingtalk-sendimage-invalid-reply-context-type-t","errorCode":null,"errorMessage":"dingtalk: SendImage: invalid reply context type %T","messagePattern":"dingtalk: SendImage: invalid reply context type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":1017,"sourceCode":"// AddDoneReaction adds a DingTalk done emotion when configured.\nfunc (p *Platform) AddDoneReaction(rctx any) {\n\trc, ok := rctx.(replyContext)\n\tif !ok || p.doneEmoji == \"\" || rc.messageID == \"\" || rc.conversationId == \"\" {\n\t\treturn\n\t}\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\tif err := p.sendEmotion(ctx, rc, p.doneEmoji, false); err != nil {\n\t\tslog.Debug(\"dingtalk: add done emotion failed\", \"error\", err)\n\t}\n}\n\n// SendImage uploads and sends an image via DingTalk oToMessages API.\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(\"dingtalk: SendImage: invalid reply context type %T\", rctx)\n\t}\n\n\tname := img.FileName\n\tif name == \"\" {\n\t\tname = \"image.png\"\n\t}\n\n\tmediaID, err := p.uploadMedia(ctx, img.Data, name, \"image\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: upload image: %w\", err)\n\t}\n\n\tslog.Debug(\"dingtalk: image uploaded\", \"media_id\", mediaID, \"size\", len(img.Data))\n\n\ttoken, err := p.getAccessToken()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: get access token: %w\", err)\n\t}","sourceCodeStart":999,"sourceCodeEnd":1035,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L999-L1035","documentation":"This error is returned by Platform.SendImage when the rctx (reply context) argument is not of the internal replyContext struct type. SendImage implements core.ImageSender and expects the reply context that the DingTalk platform itself issued (containing senderStaffId needed for the oToMessages API). Receiving any other type means the caller passed a context from a different platform or a foreign value, so the image cannot be routed to a DingTalk user.","triggerScenarios":"Calling SendImage with a rctx that is not platform/dingtalk's replyContext — e.g. passing a replyContext from the feishu/telegram platform, a nil value, or a hand-constructed context obtained outside the platform's own message pipeline.","commonSituations":"Cross-platform plugins forwarding reply contexts between adapters; custom code constructing its own reply context instead of using the one delivered with the inbound message; wiring bugs where contexts are mixed up between platforms.","solutions":["Pass exactly the reply context the DingTalk platform handed you with the inbound message — don't synthesize one","Check that you are not mixing reply contexts across platforms (a feishu context won't work here)","Ensure rctx is not nil before calling SendImage","If you need to send images outside a reply flow, use the platform's general Send API rather than SendImage"],"exampleFix":"// before: rc := someOtherPlatformReplyContext\nerr := p.SendImage(ctx, rc, img)\n// after: use the dingtalk replyContext delivered with the message\nerr := p.SendImage(ctx, dingtalkReplyCtx, img)","handlingStrategy":"type-guard","validationCode":"// Go: verify the context type before calling SendImage\nif _, ok := rctx.(dingtalk.ReplyContext); !ok {\n    return errors.New(\"sendImage: rctx is not a dingtalk reply context\")\n}","typeGuard":"func isDingTalkReplyContext(rctx any) bool {\n    _, ok := rctx.(replyContext)\n    return ok\n}","tryCatchPattern":"if err := p.SendImage(ctx, rctx, img); err != nil {\n    if strings.Contains(err.Error(), \"invalid reply context type\") {\n        slog.Error(\"wrong reply context passed to dingtalk SendImage\",\n            \"got\", fmt.Sprintf(\"%T\", rctx))\n    }\n}","preventionTips":["Always pass the reply context exactly as delivered by the platform's inbound message hook","Never share reply contexts across platform adapters","Never construct a replyContext manually; obtain it from the platform","Nil-check rctx before invoking platform-specific senders"],"tags":["dingtalk","type-mismatch","context","api-misuse"],"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"}