{"record":{"id":"05b9155d137150e7","repo":"chenhg5/cc-connect","slug":"weixin-getupdates-json-w","errorCode":null,"errorMessage":"weixin: getUpdates json: %w","messagePattern":"weixin: getUpdates json: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/client.go","lineNumber":157,"sourceCode":"\t\treturn nil, err\n\t}\n\traw, err := c.post(ctx, \"ilink/bot/getupdates\", payload, timeout, \"getUpdates\")\n\tif err != nil {\n\t\tif ctx.Err() != nil {\n\t\t\treturn nil, ctx.Err()\n\t\t}\n\t\tif errors.Is(err, context.DeadlineExceeded) {\n\t\t\treturn &getUpdatesResp{Ret: 0, Msgs: nil, GetUpdatesBuf: buf}, nil\n\t\t}\n\t\tvar ne net.Error\n\t\tif errors.As(err, &ne) && ne.Timeout() {\n\t\t\treturn &getUpdatesResp{Ret: 0, Msgs: nil, GetUpdatesBuf: buf}, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\tvar out getUpdatesResp\n\tif err := json.Unmarshal(raw, &out); err != nil {\n\t\treturn nil, fmt.Errorf(\"weixin: getUpdates json: %w\", err)\n\t}\n\treturn &out, nil\n}\n\nfunc (c *apiClient) sendMessage(ctx context.Context, msg *sendMessageReq) error {\n\tif msg == nil {\n\t\treturn fmt.Errorf(\"weixin: sendMessage: nil request\")\n\t}\n\tmsg.BaseInfo = baseInfo{ChannelVersion: channelVersion}\n\tpayload, err := json.Marshal(msg)\n\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 {","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/client.go#L139-L175","documentation":"getUpdates fetches new messages from the WeChat iLink bot API and decodes the HTTP body into getUpdatesResp. This error wraps a json.Unmarshal failure, meaning the server returned bytes that are not valid JSON or do not match the expected response schema. It usually indicates a protocol/endpoint mismatch or an HTML error page instead of JSON.","triggerScenarios":"The ilink/bot/getupdates endpoint returns malformed JSON, an HTML error page (proxy/gateway error), or a schema change (fields renamed/renumbered) that breaks json.Unmarshal into getUpdatesResp.","commonSituations":"Running an outdated client against an updated WeChat iLink API; a corporate proxy or WAF injecting an HTML block/login page; capturing a device-routed response that differs from the bot protocol.","solutions":["Log the raw response body (truncateForLog) to see what the server actually returned","Verify the bot session/ticket is still valid and re-authenticate if the API changed","Update the getUpdatesResp struct to match the current iLink API schema","Check for proxies/WAFs rewriting responses to HTML and bypass them"],"exampleFix":"// before: error hides the body\nreturn nil, fmt.Errorf(\"weixin: getUpdates json: %w\", err)\n// after: include a body snippet for diagnosis\nreturn nil, fmt.Errorf(\"weixin: getUpdates json: %w: %s\", err, truncateForLog(raw, 256))","handlingStrategy":"try-catch","validationCode":"if len(bytes.TrimSpace(raw)) == 0 { return fmt.Errorf(\"weixin: empty getUpdates body\") }","typeGuard":"func isJSON(b []byte) bool { var v any; return json.Unmarshal(b, &v) == nil }","tryCatchPattern":"out, err := getUpdates(ctx)\nif err != nil {\n\tvar jsonErr *json.UnmarshalTypeError\n\tif errors.As(err, &jsonErr) { slog.Error(\"weixin: schema drift\", \"field\", jsonErr.Field) }\n\telse if strings.Contains(err.Error(), \"json\") { slog.Error(\"weixin: non-JSON body\", \"err\", err) }\n\treturn\n}","preventionTips":["Always log a truncated raw body on unmarshal failure","Pin and track WeChat iLink protocol versions","Alert on HTML/proxy responses during polling"],"tags":["weixin","json","unmarshal","polling"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}