chenhg5/cc-connect · error
weixin: missing context_token for peer
Error message
weixin: missing context_token for peer %q - user must send a message to the bot first
What it means
WeChat's ilink sendmessage API requires a context_token captured from the user's most recent inbound message. If the reply context has no context_token and none is cached for the peer user, sendChunks refuses to send and returns this error, since any send attempt would be rejected by the server.
Solutions
- Ask the user to send any message to the bot first, then reply within the token validity window
- Persist state_dir so context tokens survive restarts
- Convert proactive pushes into replies triggered by user activity
- Reduce push volume so tokens don't expire between sends
Defensive patterns
Strategy: fallback
Validate before calling
if strings.TrimSpace(rc.ContextToken) == "" {
// cannot push; queue message until the user messages the bot
queueForLaterReply(peerUserID, content)
return nil
} Try / catch
if err := p.Send(ctx, rc, msg); err != nil && strings.Contains(err.Error(), "missing context_token") {
log.Warn("user must message the bot first; queuing", "peer", rc.PeerUserID)
queueForLaterReply(rc.PeerUserID, msg)
} Prevention
- Never push to users who haven't messaged the bot
- Persist state_dir so captured tokens survive restarts
- Reply promptly while the user's token is fresh
- Treat pushes to silent peers as best-effort with fallback queuing
When it happens
Trigger: The bot attempts a proactive push (Send, cron, timer) to a peer who has never messaged the bot, or whose captured context_token is missing/expired from the token cache and sync buffer.
Common situations: Bot restarted with an empty state_dir losing cached tokens; user's context_token expired after inactivity; first-ever message to a new user attempted as a push instead of waiting for an inbound message.
Related errors
- -2
- antigravity: unknown permission request
- session is closed
- weixin: context_token is required for send
- weixin: convert to AMR
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/4cfaecea348cbf4b.
Report an issue: GitHub.
Appendix: source
Thrown at platform/weixin/weixin.go:820
}
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)
total := len(chunks)
for i, chunk := range chunks {
// Add delay between chunks to avoid rate limiting (except for first chunk)
if i > 0 {
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(weixinChunkSendDelay):
}
}
err := p.sendChunk(ctx, rc, chunk)
if err != nil {
slog.Error("weixin: chunk send failed, message incomplete",View on GitHub (pinned to 4000b2338a)