chenhg5/cc-connect · error
weixin: invalid reply context
Error message
weixin: invalid reply context
What it means
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.
Source
Thrown at platform/weixin/weixin.go:807
slog.Error("weixin: push_path_budget_exceeded",
"path", string(path),
"used", len(p.sendQuotaTimes),
"limit", p.sendQuotaLimit,
"window", p.sendQuotaWindow.String(),
"hint", "ilink throttles the bot after roughly 5-6 pushes per window — reduce cron/timer pushes or re-login later",
)
return fmt.Errorf("weixin: push budget exhausted (%d push messages in the last %s); "+
"ilink throttles the bot after roughly 5-6 pushes per window — reduce messages or re-login later", p.sendQuotaLimit, p.sendQuotaWindow)
}
p.sendQuotaTimes = append(p.sendQuotaTimes, now)
p.sendQuotaMu.Unlock()
return nil
}
func (p *Platform) sendChunks(ctx context.Context, replyCtx any, content string, path sendPath) error {
rc, ok := replyCtx.(*replyContext)
if !ok || rc == nil {
return fmt.Errorf("weixin: invalid reply context")
}
if err := p.checkSendQuota(ctx, path); err != nil {
return err
}
if strings.TrimSpace(rc.contextToken) == "" {
rc.contextToken = p.getContextToken(rc.peerUserID)
}
if strings.TrimSpace(rc.contextToken) == "" {
slog.Error("weixin: cannot send message - missing context_token",
"peer", rc.peerUserID,
"content_preview", truncatePreview(content, 100),
"hint", "user needs to send a message to the bot first so a context_token can be captured")
return fmt.Errorf("weixin: missing context_token for peer %q - user must send a message to the bot first", rc.peerUserID)
}
if strings.TrimSpace(content) == "" {
return nil
}
chunks := splitUTF8(content, maxWeixinChunk)View on GitHub (pinned to 4000b2338a)
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
Example fix
// before err := p.Send(nil, "hello") // nil context // after rc := p.NewReplyContext(peerUserID) // obtain a valid *replyContext err := p.Send(rc, "hello")
Defensive patterns
Strategy: type-guard
Validate before calling
rc, ok := ctxValue.(*weixin.ReplyContext)
if !ok || rc == nil {
return errors.New("no valid weixin reply context")
} Type guard
func validReplyContext(v any) bool {
rc, ok := v.(*replyContext)
return ok && rc != nil
} Try / catch
if err := p.Send(rc, msg); err != nil && strings.Contains(err.Error(), "invalid reply context") {
log.Error("reply context from wrong/old platform instance; recreate it")
} Prevention
- Only pass reply contexts from the same live platform instance
- Never serialize/persist reply contexts across restarts
- Check for nil before calling Send/Reply
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- bridge: invalid reply context type %T
- bridge: invalid reply context
- dingtalk: invalid reply context type %T
- line: invalid reply context type %T
- max: unexpected replyCtx type %T
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/93eb76a23572f14d.
Report an issue: GitHub.