{"record":{"id":"3f3d892414eedac9","repo":"chenhg5/cc-connect","slug":"discord-invalid-reply-context-type-t","errorCode":null,"errorMessage":"discord: invalid reply context type %T","messagePattern":"discord: invalid reply context type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/discord/discord.go","lineNumber":960,"sourceCode":"\tif action, found := strings.CutPrefix(customID, \"perm:\"); found {\n\t\tswitch action {\n\t\tcase \"allow\", \"deny\":\n\t\t\treturn action, true, true\n\t\tcase \"allow_all\":\n\t\t\treturn \"allow all\", true, true\n\t\t}\n\t}\n\treturn \"\", false, false\n}\n\nfunc (p *Platform) Reply(ctx context.Context, rctx any, content string) error {\n\tswitch rc := rctx.(type) {\n\tcase *interactionReplyCtx:\n\t\treturn p.sendInteraction(rc, content)\n\tcase replyContext:\n\t\treturn p.sendChannelReply(rc, content)\n\tdefault:\n\t\treturn fmt.Errorf(\"discord: invalid reply context type %T\", rctx)\n\t}\n}\n\n// Send sends a new message (not a reply).\nfunc (p *Platform) Send(ctx context.Context, rctx any, content string) error {\n\tswitch rc := rctx.(type) {\n\tcase *interactionReplyCtx:\n\t\treturn p.sendInteraction(rc, content)\n\tcase replyContext:\n\t\treturn p.sendChannel(rc, content)\n\tdefault:\n\t\treturn fmt.Errorf(\"discord: invalid reply context type %T\", rctx)\n\t}\n}\n\n// sendInteraction delivers a message through the Discord interaction response\n// mechanism. The first call edits the deferred \"thinking\" response; subsequent\n// calls create followup messages.","sourceCodeStart":942,"sourceCodeEnd":978,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/discord/discord.go#L942-L978","documentation":"Reply() received a reply-context value that is neither the platform's internal *interactionReplyCtx nor its replyContext struct. The Discord platform creates these contexts itself when a message arrives, so hitting the default branch means a foreign or zero-value context was passed in — typically a reply context captured from a different platform and reused on this one.","triggerScenarios":"Passing nil or a ReplyCtx produced by another platform (e.g. a Feishu or Telegram reply context) into discord.Platform.Reply; storing a ReplyCtx across platforms and replaying it; calling Reply with an empty any value from custom engine code.","commonSituations":"Bridges or forwarding logic that routes messages between platforms and copies ReplyCtx without checking which platform produced it; tests or scripts that hand-craft reply contexts; a nil ReplyCtx after an engine bug fails to attach one.","solutions":["Ensure Reply is only called with the ReplyCtx that the Discord platform itself attached to core.Message — never reuse contexts across platforms","Check that the originating message actually came from the Discord platform before calling p.Reply","Guard the call site with a nil/origin check on rctx before invoking Reply","If bridging, capture the content and send via Send with a Discord-native context instead of replaying a foreign one"],"exampleFix":"// before\nerr := discordPlatform.Reply(ctx, msg.ReplyCtx, out)\n// after\nif rc, ok := msg.ReplyCtx.(discord.ReplyContext); ok {\n    err = discordPlatform.Reply(ctx, rc, out)\n}","handlingStrategy":"type-guard","validationCode":"if rctx == nil {\n    return fmt.Errorf(\"no reply context: message did not originate from discord\")\n}","typeGuard":"func isDiscordReplyCtx(rctx any) bool {\n    switch rctx.(type) {\n    case *discordinteractionReplyCtx, discordreplyContext:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"if err := p.Reply(ctx, rctx, content); err != nil {\n    if strings.Contains(err.Error(), \"invalid reply context type\") {\n        slog.Warn(\"non-discord reply context; dropping reply\")\n        return nil\n    }\n    return err\n}","preventionTips":["Never reuse a ReplyCtx across platform adapters","Only pass contexts attached to messages received from the Discord platform","Nil-check reply contexts before replying","Add a unit test asserting engine routing keeps contexts platform-local"],"tags":["discord","type-mismatch","programming-error"],"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"}