{"record":{"id":"71f44e67362a539b","repo":"larksuite/cli","slug":"parse-response-w","errorCode":null,"errorMessage":"parse response: %w","messagePattern":"parse response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/identitydiag/diagnostics.go","lineNumber":427,"sourceCode":"\t\tMsg  string `json:\"msg\"`\n\t\tData struct {\n\t\t\tOpenID  string `json:\"open_id\"`\n\t\t\tAppName string `json:\"app_name\"`\n\t\t} `json:\"bot\"`\n\t}\n\tparseErr := json.Unmarshal(body, &envelope)\n\n\tif resp.StatusCode >= 400 {\n\t\t// Lark error responses are usually `{code, msg}` envelopes even on\n\t\t// non-2xx — surface them when present so callers see why bot auth\n\t\t// was rejected, not just the bare HTTP code.\n\t\tif parseErr == nil && envelope.Code != 0 {\n\t\t\treturn nil, fmt.Errorf(\"HTTP %d: [%d] %s\", resp.StatusCode, envelope.Code, envelope.Msg)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"HTTP %d\", resp.StatusCode)\n\t}\n\tif parseErr != nil {\n\t\treturn nil, fmt.Errorf(\"parse response: %w\", parseErr)\n\t}\n\tif envelope.Code != 0 {\n\t\treturn nil, fmt.Errorf(\"[%d] %s\", envelope.Code, envelope.Msg)\n\t}\n\tif envelope.Data.OpenID == \"\" {\n\t\treturn nil, errors.New(\"open_id is empty\")\n\t}\n\treturn &botInfo{OpenID: envelope.Data.OpenID, AppName: envelope.Data.AppName}, nil\n}\n\nfunc fillTokenFields(id *Identity, token *larkauth.StoredUAToken) {\n\tid.TokenStatus = larkauth.TokenStatus(token)\n\tid.Scope = token.Scope\n\tid.ExpiresAt = formatMillis(token.ExpiresAt)\n\tid.RefreshExpiresAt = formatMillis(token.RefreshExpiresAt)\n\tid.GrantedAt = formatMillis(token.GrantedAt)\n}\n","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/identitydiag/diagnostics.go#L409-L445","documentation":"This error wraps a failure to parse the HTTP response body of the bot-info call as JSON (or decode it into the envelope struct). It only fires when the status code was < 400 — i.e. the server said OK but the body was not the expected {code,msg,data} shape. The %w preserves the json/decode error for diagnosis.","triggerScenarios":"fetchBotInfo gets a 2xx response but json.Unmarshal/decode of the body into the envelope fails (parseErr != nil). Reached via diagnoseBot or diagnoseExternalBot.","commonSituations":"A middlebox (proxy, captive portal, security appliance) intercepting HTTPS and returning HTML; truncated response due to connection reset mid-body; wrong endpoint serving JSON of a different shape; content-encoding mismatch (gzip issues).","solutions":["Read the wrapped parse error for the exact JSON syntax/shape problem.","Check for a proxy or TLS-intercepting appliance rewriting responses; bypass it for open.feishu.cn / open.larksuite.com.","Retry the request — a truncated 2xx body is often transient network damage.","Confirm the configured Open endpoint actually serves the Lark OpenAPI (no typo'd override)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"info, err := fetchBotInfo(ctx, f, cfg, token)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"parse response:\") {\n        // 2xx but non-JSON: middlebox interference or truncation — retry once, then surface\n        if retryErr := retry.Once(ctx, func() error { _, err = fetchBotInfo(ctx, f, cfg, token); return err }); retryErr != nil {\n            return fmt.Errorf(\"non-JSON response from endpoint, check proxy: %w\", retryErr)\n        }\n        return nil\n    }\n    return err\n}","preventionTips":["Exclude Lark endpoints from TLS-inspecting appliances.","Avoid flaky networks or enforce keep-alives for diagnostics calls.","Verify endpoint overrides serve the real Lark OpenAPI.","Test connectivity with a plain JSON fetch to the endpoint before running full diagnostics."],"tags":["json","parse-error","http","network"],"backgroundTag":"json-parse-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"}