{"record":{"id":"0eb3745ae48ad437","repo":"larksuite/cli","slug":"connection-check-decode-w-body-s","errorCode":null,"errorMessage":"connection check: decode: %w (body=%s)","messagePattern":"connection check: decode: %w \\(body=(.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/event/consume/remote_preflight.go","lineNumber":30,"sourceCode":")\n\ntype APIClient = event.APIClient\n\n// CheckRemoteConnections returns the count of active WebSocket connections for this app.\nfunc CheckRemoteConnections(ctx context.Context, client APIClient) (int, error) {\n\traw, err := client.CallAPI(ctx, \"GET\", \"/open-apis/event/v1/connection\", nil)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"connection check: %w\", err)\n\t}\n\tvar result struct {\n\t\tCode int    `json:\"code\"`\n\t\tMsg  string `json:\"msg\"`\n\t\tData struct {\n\t\t\tOnlineInstanceCnt int `json:\"online_instance_cnt\"`\n\t\t} `json:\"data\"`\n\t}\n\tif err := json.Unmarshal(raw, &result); err != nil {\n\t\treturn 0, fmt.Errorf(\"connection check: decode: %w (body=%s)\", err, truncateForError(raw))\n\t}\n\t// Distinguish \"verified zero\" from \"check failed\" — non-zero code decodes Cnt=0.\n\tif result.Code != 0 {\n\t\treturn 0, fmt.Errorf(\"connection check: api error code=%d msg=%q\", result.Code, result.Msg)\n\t}\n\treturn result.Data.OnlineInstanceCnt, nil\n}\n\n// truncateForError bounds length and collapses control chars to defang log injection.\nfunc truncateForError(b []byte) string {\n\tconst max = 256\n\ts := event.TruncateDiagnostic(string(b), max, \"…(truncated)\")\n\tout := make([]byte, 0, len(s))\n\tfor _, r := range s {\n\t\tif r == '\\n' || r == '\\r' || r == '\\t' {\n\t\t\tout = append(out, ' ')\n\t\t\tcontinue\n\t\t}","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/event/consume/remote_preflight.go#L12-L48","documentation":"After the connection-check API responds, CheckRemoteConnections decodes the body into a struct with code/msg/data.online_instance_cnt. If json.Unmarshal fails, the error is wrapped as 'connection check: decode: %w (body=%s)' and the (length-bounded, control-character-defanged) raw body is embedded for diagnosis. This means the endpoint was reachable but the payload was not the expected JSON shape.","triggerScenarios":"json.Unmarshal of the CallAPI response body fails: HTML error/interstitial pages, empty body, truncation, wrong Content-Type gateway responses, or a proxy returning non-JSON text on GET /open-apis/event/v1/connection.","commonSituations":"Gateway/WAF returning an HTML 502 page, captive portal or proxy intercepting the request, API version change altering the response schema, response body cut off mid-JSON.","solutions":["Read the embedded body= snippet in the error to see what was actually returned (HTML? empty? partial JSON?).","Verify the base URL points at the official open domain and that no proxy is rewriting responses.","Retry the request; if the body is consistently truncated, check for intermediary proxies or MTU/timeout issues.","Confirm the API contract still matches {code,msg,data.online_instance_cnt} and update the struct if the service schema changed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the raw response looks like the expected JSON envelope before decoding\nvar peek struct {\n\tCode *int `json:\"code\"`\n}\nif err := json.Unmarshal(raw, &peek); err != nil || peek.Code == nil {\n\t// not the expected schema: log truncateForError(raw) and abort/retry\n}","typeGuard":null,"tryCatchPattern":"_, err := consume.CheckRemoteConnections(ctx, client)\nif err != nil {\n\tvar decErr *json.UnmarshalError\n\tif errors.As(err, &decErr) || strings.Contains(err.Error(), \"decode:\") {\n\t\t// body was not JSON: dump body snippet, retry or fall back\n\t}\n}","preventionTips":["Confirm the base URL hits the official gateway, not an intercepting proxy.","Check for corporate WAF/SSO pages that return HTML for API paths.","Pin the API/service version the client was built against and re-verify after upgrades.","Log the response body (defanged) on decode failure to speed diagnosis."],"tags":["json","decode","http","preflight"],"backgroundTag":"json-decode-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}