{"record":{"id":"3e8e84256633ee5d","repo":"chenhg5/cc-connect","slug":"weixin-sendmessage-ret-d-errcode-d-errmsg-s","errorCode":null,"errorMessage":"weixin: sendMessage: ret=%d errcode=%d errmsg=%s","messagePattern":"weixin: sendMessage: ret=(.+?) errcode=(.+?) errmsg=(.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/client.go","lineNumber":186,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\traw, err := c.post(ctx, \"ilink/bot/sendmessage\", payload, 0, \"sendMessage\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(bytes.TrimSpace(raw)) == 0 {\n\t\treturn nil\n\t}\n\tvar resp sendMessageResp\n\tif err := json.Unmarshal(raw, &resp); err != nil {\n\t\treturn fmt.Errorf(\"weixin: sendMessage: response json: %w: %s\", err, truncateForLog(raw, 256))\n\t}\n\tif resp.Ret != 0 {\n\t\tslog.Warn(\"weixin: sendMessage declined by API\",\n\t\t\t\"ret\", resp.Ret, \"errcode\", resp.Errcode, \"errmsg\", resp.Errmsg,\n\t\t\t\"content_len\", len(payload))\n\t\treturn fmt.Errorf(\"weixin: sendMessage: ret=%d errcode=%d errmsg=%s\",\n\t\t\tresp.Ret, resp.Errcode, resp.Errmsg)\n\t}\n\treturn nil\n}\n\nfunc (c *apiClient) getUploadURL(ctx context.Context, req getUploadURLRequest) (*getUploadURLResponse, error) {\n\treq.BaseInfo = baseInfo{ChannelVersion: channelVersion}\n\tpayload, err := json.Marshal(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\traw, err := c.post(ctx, \"ilink/bot/getuploadurl\", payload, 0, \"getUploadUrl\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar out getUploadURLResponse\n\tif err := json.Unmarshal(raw, &out); err != nil {\n\t\treturn nil, fmt.Errorf(\"weixin: getUploadUrl json: %w\", err)","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/client.go#L168-L204","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the logged errcode/errmsg from the slog.Warn line to identify the API's reason","Refresh the session/context_token (re-authenticate or getConfig) and retry","Check content length and split or trim oversized messages before sending","Add backoff/retry for rate-limit style errcodes and re-establish the session for auth errcodes"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := sendText(...); err != nil {\n\tvar apiErr APIError\n\tif errors.As(err, &apiErr) {\n\t\tif isAuthErrcode(apiErr.Errcode) { refreshSession(); return retry() }\n\t\tif isRateLimitErrcode(apiErr.Errcode) { return retryWithBackoff() }\n\t}\n\treturn err\n}","preventionTips":["Refresh context tokens proactively before expiry","Split messages to stay under content-length limits","Classify errcodes: retryable (rate limit) vs fatal (auth/ban)"],"tags":["weixin","api-error","send","declined"],"backgroundTag":"api-error-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}