{"record":{"id":"93eb76a23572f14d","repo":"chenhg5/cc-connect","slug":"weixin-invalid-reply-context-93eb76","errorCode":null,"errorMessage":"weixin: invalid reply context","messagePattern":"weixin: invalid reply context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/weixin.go","lineNumber":807,"sourceCode":"\t\tslog.Error(\"weixin: push_path_budget_exceeded\",\n\t\t\t\"path\", string(path),\n\t\t\t\"used\", len(p.sendQuotaTimes),\n\t\t\t\"limit\", p.sendQuotaLimit,\n\t\t\t\"window\", p.sendQuotaWindow.String(),\n\t\t\t\"hint\", \"ilink throttles the bot after roughly 5-6 pushes per window — reduce cron/timer pushes or re-login later\",\n\t\t)\n\t\treturn fmt.Errorf(\"weixin: push budget exhausted (%d push messages in the last %s); \"+\n\t\t\t\"ilink throttles the bot after roughly 5-6 pushes per window — reduce messages or re-login later\", p.sendQuotaLimit, p.sendQuotaWindow)\n\t}\n\tp.sendQuotaTimes = append(p.sendQuotaTimes, now)\n\tp.sendQuotaMu.Unlock()\n\treturn nil\n}\n\nfunc (p *Platform) sendChunks(ctx context.Context, replyCtx any, content string, path sendPath) error {\n\trc, ok := replyCtx.(*replyContext)\n\tif !ok || rc == nil {\n\t\treturn fmt.Errorf(\"weixin: invalid reply context\")\n\t}\n\tif err := p.checkSendQuota(ctx, path); err != nil {\n\t\treturn err\n\t}\n\tif strings.TrimSpace(rc.contextToken) == \"\" {\n\t\trc.contextToken = p.getContextToken(rc.peerUserID)\n\t}\n\tif strings.TrimSpace(rc.contextToken) == \"\" {\n\t\tslog.Error(\"weixin: cannot send message - missing context_token\",\n\t\t\t\"peer\", rc.peerUserID,\n\t\t\t\"content_preview\", truncatePreview(content, 100),\n\t\t\t\"hint\", \"user needs to send a message to the bot first so a context_token can be captured\")\n\t\treturn fmt.Errorf(\"weixin: missing context_token for peer %q - user must send a message to the bot first\", rc.peerUserID)\n\t}\n\tif strings.TrimSpace(content) == \"\" {\n\t\treturn nil\n\t}\n\tchunks := splitUTF8(content, maxWeixinChunk)","sourceCodeStart":789,"sourceCodeEnd":825,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/weixin.go#L789-L825","documentation":"sendChunks expects replyCtx to be the platform-internal *replyContext produced by newReplyContext. If the caller passes nil or a value of any other type, the type assertion fails and this error is returned — it signals an internal API misuse, not a user-facing condition.","triggerScenarios":"Reply() or Send() invoked with a reply context that is nil or was created by a different platform type; passing a string/struct instead of the *replyContext the weixin platform returned.","commonSituations":"Swapping platform implementations while reusing cached reply contexts; storing a reply context across a platform restart so the old concrete type no longer matches; passing nil context into Send directly.","solutions":["Only pass reply contexts obtained from the same live weixin Platform instance","If sending a fresh (non-reply) message, use the correct Send path so a valid context is built","Recreate the platform and its reply contexts rather than reusing serialized/old ones"],"exampleFix":"// before\nerr := p.Send(nil, \"hello\")            // nil context\n// after\nrc := p.NewReplyContext(peerUserID)    // obtain a valid *replyContext\nerr := p.Send(rc, \"hello\")","handlingStrategy":"type-guard","validationCode":"rc, ok := ctxValue.(*weixin.ReplyContext)\nif !ok || rc == nil {\n    return errors.New(\"no valid weixin reply context\")\n}","typeGuard":"func validReplyContext(v any) bool {\n    rc, ok := v.(*replyContext)\n    return ok && rc != nil\n}","tryCatchPattern":"if err := p.Send(rc, msg); err != nil && strings.Contains(err.Error(), \"invalid reply context\") {\n    log.Error(\"reply context from wrong/old platform instance; recreate it\")\n}","preventionTips":["Only pass reply contexts from the same live platform instance","Never serialize/persist reply contexts across restarts","Check for nil before calling Send/Reply"],"tags":["go","weixin","type-assertion","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"}