chenhg5/cc-connect · error
weixin: getUpdates json: %w
Error message
weixin: getUpdates json: %w
What it means
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.
Source
Thrown at platform/weixin/client.go:157
return nil, err
}
raw, err := c.post(ctx, "ilink/bot/getupdates", payload, timeout, "getUpdates")
if err != nil {
if ctx.Err() != nil {
return nil, ctx.Err()
}
if errors.Is(err, context.DeadlineExceeded) {
return &getUpdatesResp{Ret: 0, Msgs: nil, GetUpdatesBuf: buf}, nil
}
var ne net.Error
if errors.As(err, &ne) && ne.Timeout() {
return &getUpdatesResp{Ret: 0, Msgs: nil, GetUpdatesBuf: buf}, nil
}
return nil, err
}
var out getUpdatesResp
if err := json.Unmarshal(raw, &out); err != nil {
return nil, fmt.Errorf("weixin: getUpdates json: %w", err)
}
return &out, nil
}
func (c *apiClient) sendMessage(ctx context.Context, msg *sendMessageReq) error {
if msg == nil {
return fmt.Errorf("weixin: sendMessage: nil request")
}
msg.BaseInfo = baseInfo{ChannelVersion: channelVersion}
payload, err := json.Marshal(msg)
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 {View on GitHub (pinned to 4000b2338a)
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
Example fix
// before: error hides the body
return nil, fmt.Errorf("weixin: getUpdates json: %w", err)
// after: include a body snippet for diagnosis
return nil, fmt.Errorf("weixin: getUpdates json: %w: %s", err, truncateForLog(raw, 256)) Defensive patterns
Strategy: try-catch
Validate before calling
if len(bytes.TrimSpace(raw)) == 0 { return fmt.Errorf("weixin: empty getUpdates body") } Type guard
func isJSON(b []byte) bool { var v any; return json.Unmarshal(b, &v) == nil } Try / catch
out, err := getUpdates(ctx)
if err != nil {
var jsonErr *json.UnmarshalTypeError
if errors.As(err, &jsonErr) { slog.Error("weixin: schema drift", "field", jsonErr.Field) }
else if strings.Contains(err.Error(), "json") { slog.Error("weixin: non-JSON body", "err", err) }
return
} Prevention
- Always log a truncated raw body on unmarshal failure
- Pin and track WeChat iLink protocol versions
- Alert on HTML/proxy responses during polling
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- get_qrcode_status json: %w
- get_bot_qrcode json: %w
- invalid json response: %w
- weixin: sendMessage: response json: %w: %s
- weixin: getUploadUrl json: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/05b9155d137150e7.
Report an issue: GitHub.