chenhg5/cc-connect · error

weixin: context_token is required for send

Error message

weixin: context_token is required for send

What it means

WeChat iLink outbound sends require a context_token obtained from the conversation config; the client enforces this before building the request. sendText refuses to send when the token is empty because the API would reject the message anyway.

Solutions

  1. Ensure getConfig runs and its result is cached per user before any send
  2. Fail earlier: propagate the getConfig error instead of continuing with an empty token
  3. Re-fetch config on this error and retry the send once
  4. Verify session persistence so tokens survive restarts

Example fix

// before
if err := getConfig(...); err != nil { slog.Warn("..."); }
c.sendText(ctx, to, text, token, id) // token may be empty
// after
if err := getConfig(...); err != nil { return fmt.Errorf("weixin: get config: %w", err) }
c.sendText(ctx, to, text, token, id)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(contextToken) == "" { return errors.New("cannot send: context_token missing; fetch config first") }

Type guard

func hasContextToken(t string) bool { return strings.TrimSpace(t) != "" }

Try / catch

if err := sendText(ctx, to, text, token, id); err != nil {
	if strings.Contains(err.Error(), "context_token is required") {
		if tok, cerr := fetchContextToken(ctx, to); cerr == nil { return sendText(ctx, to, text, tok, id) }
	}
	return err
}

Prevention

When it happens

Trigger: sendText invoked with an empty contextToken — typically when the getConfig step was skipped, failed silently, or the token expired and was cleared before this send.

Common situations: Bot restart losing cached per-user context tokens; getConfig previously failed (errors 1716/1717) and the caller proceeded anyway; first message to a user before config was ever fetched.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/c502ec2a5b3a5c4e. Report an issue: GitHub.

Appendix: source

Thrown at platform/weixin/client.go:255

func (c *apiClient) sendTyping(ctx context.Context, userID, typingTicket string, status int) error {
	req := sendTypingReq{
		IlinkUserID:  userID,
		TypingTicket: typingTicket,
		Status:       status,
		BaseInfo:     baseInfo{ChannelVersion: channelVersion},
	}
	payload, err := json.Marshal(req)
	if err != nil {
		return err
	}
	_, err = c.post(ctx, "ilink/bot/sendtyping", payload, 0, "sendTyping")
	return err
}

func (c *apiClient) sendText(ctx context.Context, to, text, contextToken, clientID string) error {
	if strings.TrimSpace(contextToken) == "" {
		return fmt.Errorf("weixin: context_token is required for send")
	}
	items := []messageItem{}
	if strings.TrimSpace(text) != "" {
		items = append(items, messageItem{
			Type:     messageItemText,
			TextItem: &textItem{Text: text},
		})
	}
	if len(items) == 0 {
		return fmt.Errorf("weixin: sendText: empty item_list")
	}
	msg := sendMessageReq{
		Msg: weixinOutboundMsg{
			FromUserID:   "",
			ToUserID:     to,
			ClientID:     clientID,
			MessageType:  messageTypeBot,
			MessageState: messageStateFinish,

View on GitHub (pinned to 4000b2338a)