chenhg5/cc-connect · error

weixin: sendMessage: ret=%d errcode=%d errmsg=%s

Error message

weixin: sendMessage: ret=%d errcode=%d errmsg=%s

What it means

The WeChat sendMessage endpoint answered with valid JSON but a non-zero Ret, meaning the API refused the message. The code logs ret/errcode/errmsg at warn level (with content length) and returns them as an error so callers know delivery failed.

Source

Thrown at platform/weixin/client.go:186

	if err != nil {
		return err
	}
	raw, err := c.post(ctx, "ilink/bot/sendmessage", payload, 0, "sendMessage")
	if err != nil {
		return err
	}
	if len(bytes.TrimSpace(raw)) == 0 {
		return nil
	}
	var resp sendMessageResp
	if err := json.Unmarshal(raw, &resp); err != nil {
		return fmt.Errorf("weixin: sendMessage: response json: %w: %s", err, truncateForLog(raw, 256))
	}
	if resp.Ret != 0 {
		slog.Warn("weixin: sendMessage declined by API",
			"ret", resp.Ret, "errcode", resp.Errcode, "errmsg", resp.Errmsg,
			"content_len", len(payload))
		return fmt.Errorf("weixin: sendMessage: ret=%d errcode=%d errmsg=%s",
			resp.Ret, resp.Errcode, resp.Errmsg)
	}
	return nil
}

func (c *apiClient) getUploadURL(ctx context.Context, req getUploadURLRequest) (*getUploadURLResponse, error) {
	req.BaseInfo = baseInfo{ChannelVersion: channelVersion}
	payload, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	raw, err := c.post(ctx, "ilink/bot/getuploadurl", payload, 0, "getUploadUrl")
	if err != nil {
		return nil, err
	}
	var out getUploadURLResponse
	if err := json.Unmarshal(raw, &out); err != nil {
		return nil, fmt.Errorf("weixin: getUploadUrl json: %w", err)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the logged errcode/errmsg from the slog.Warn line to identify the API's reason
  2. Refresh the session/context_token (re-authenticate or getConfig) and retry
  3. Check content length and split or trim oversized messages before sending
  4. Add backoff/retry for rate-limit style errcodes and re-establish the session for auth errcodes
Defensive patterns

Strategy: retry

Try / catch

if err := sendText(...); err != nil {
	var apiErr APIError
	if errors.As(err, &apiErr) {
		if isAuthErrcode(apiErr.Errcode) { refreshSession(); return retry() }
		if isRateLimitErrcode(apiErr.Errcode) { return retryWithBackoff() }
	}
	return err
}

Prevention

When it happens

Trigger: WeChat rejects the outbound message: invalid context_token, expired ticket/session, message to a user the bot cannot reach, content policy rejection, or rate limiting — anything the API reports via ret/errcode/errmsg.

Common situations: Stale context_token after re-login of the linked account; banned or restricted bot account; sending too fast and hitting server-side rate limits; oversized message content.

Related errors


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