chenhg5/cc-connect · error
get_bot_qrcode json: %w
Error message
get_bot_qrcode json: %w
What it means
After a successful HTTP 200 from `get_bot_qrcode`, weixinFetchBotQRCode decodes the response body into weixinBotQRResponse with json.Unmarshal. If the body is not valid JSON (or has the wrong types), this error wraps the unmarshal failure. It means the server replied but not with the expected JSON document.
Source
Thrown at cmd/cc-connect/weixin.go:440
}
func weixinFetchBotQRCode(ctx context.Context, apiBase, botType, routeTag string, debug bool) (*weixinBotQRResponse, error) {
base := strings.TrimRight(apiBase, "/") + "/"
u, err := url.Parse(base)
if err != nil {
return nil, err
}
u = u.JoinPath("ilink", "bot", "get_bot_qrcode")
q := u.Query()
q.Set("bot_type", botType)
u.RawQuery = q.Encode()
raw, err := weixinHTTPGet(ctx, u.String(), routeTag, debug)
if err != nil {
return nil, fmt.Errorf("get_bot_qrcode: %w", err)
}
var out weixinBotQRResponse
if err := json.Unmarshal(raw, &out); err != nil {
return nil, fmt.Errorf("get_bot_qrcode json: %w", err)
}
return &out, nil
}
func weixinPollQRStatus(ctx context.Context, apiBase, qrKey, routeTag string, debug bool) (*weixinQRStatusResponse, error) {
base := strings.TrimRight(apiBase, "/") + "/"
u, err := url.Parse(base)
if err != nil {
return nil, err
}
u = u.JoinPath("ilink", "bot", "get_qrcode_status")
q := u.Query()
q.Set("qrcode", qrKey)
u.RawQuery = q.Encode()
pollCtx, cancel := context.WithTimeout(ctx, weixinQRPollTimeout+2*time.Second)
defer cancel()
View on GitHub (pinned to 4000b2338a)
Solutions
- Log/dump the raw response body to see what was actually returned
- Check for proxy/captive-portal interference returning HTML with status 200
- Compare the response shape against weixinBotQRResponse and update the struct if the API schema changed
- Verify the endpoint URL is the real ilink API and not a redirect target
Defensive patterns
Strategy: type-guard
Validate before calling
if !json.Valid(raw) {
return fmt.Errorf("get_bot_qrcode: non-JSON response: %.100s", raw)
} Type guard
func looksLikeBotQR(raw []byte) bool {
var probe struct { QRKey string `json:"qr_key"` }
return json.Unmarshal(raw, &probe) == nil && probe.QRKey != ""
} Try / catch
raw, err := weixinHTTPGet(ctx, u, routeTag, debug)
if err != nil { return err }
if !looksLikeBotQR(raw) {
return fmt.Errorf("get_bot_qrcode: unexpected payload: %.200s", raw)
} Prevention
- Bypass proxies/captive portals for API hosts
- Log raw bodies on parse failure to spot schema drift
- Pin and review the ilink API version you target
- Validate response shapes in CI against a fixture
When it happens
Trigger: GET to `ilink/bot/get_bot_qrcode` returns 200 with an HTML error page, empty body, or JSON whose fields do not match weixinBotQRResponse's types (e.g. a string where a number is expected).
Common situations: A transparent proxy or captive portal intercepting the request and returning HTML; API version change altering the response schema; wrong endpoint path returning a 200 text page.
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
- invalid json response: %w
- weixin: getUpdates json: %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/2459b54cf8755ad9.
Report an issue: GitHub.