{"record":{"id":"7a16914c91909118","repo":"zed-industries/zed","slug":"request-failed-with-status-body","errorCode":null,"errorMessage":"Request failed with status: {:?}\nBody: {}","messagePattern":"Request failed with status: (.+?)\nBody: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/edit_prediction/src/mercury.rs","lineNumber":188,"sourceCode":"                .send(request)\n                .await\n                .context(\"Failed to send request\")?;\n\n            let mut body: Vec<u8> = Vec::new();\n            response\n                .body_mut()\n                .read_to_end(&mut body)\n                .await\n                .context(\"Failed to read response body\")?;\n\n            if !response.status().is_success() {\n                if response.status() == StatusCode::PAYMENT_REQUIRED {\n                    anyhow::bail!(MercuryPaymentRequiredError(\n                        mercury_payment_required_message(&body),\n                    ));\n                }\n\n                anyhow::bail!(\n                    \"Request failed with status: {:?}\\nBody: {}\",\n                    response.status(),\n                    String::from_utf8_lossy(&body),\n                );\n            };\n\n            let mut response: open_ai::Response =\n                serde_json::from_slice(&body).context(\"Failed to parse response\")?;\n\n            let id = mem::take(&mut response.id);\n            let response_str = text_from_response(response).unwrap_or_default();\n\n            if let Some(debug_tx) = &debug_tx {\n                debug_tx\n                    .unbounded_send(DebugEvent::EditPredictionFinished(\n                        EditPredictionFinishedDebugEvent {\n                            buffer: active_buffer.downgrade(),\n                            model_output: Some(response_str.clone()),","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/edit_prediction/src/mercury.rs#L170-L206","documentation":"Mercury completion request handling: after reading the body, any non-2xx status that is not 402 (which gets the dedicated payment error) bails with the debug-formatted status and the lossy-UTF-8 body (mercury.rs:188). The body is Mercury's error payload and is the key to diagnosing the failure.","triggerScenarios":"The Mercury API returning 401 (invalid/expired bearer token loaded from the credentials store), 429 (rate limited), 5xx (service incident), or an HTML error page from a proxy in front of the endpoint.","commonSituations":"Stale credentials after token rotation; heavy prediction usage hitting rate limits; Zed-side incidents; corporate proxies returning their own error pages instead of the API response.","solutions":["For 401, trigger a credential refresh (sign out/in) so a valid Bearer token is sent.","For 429, pause prediction usage and retry after the limit resets.","For 5xx, retry later; check Zed status for incidents.","Read the Body field — if it is HTML from a proxy, fix network egress instead of auth."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Branch on the embedded status: 401 → stop and refresh credentials; 429/5xx → retry with backoff; log the body verbatim (it may be JSON or proxy HTML, which itself distinguishes network from API failure).","preventionTips":["Refresh credentials proactively when tokens have a known TTL.","Read the body before assuming API fault — HTML bodies point at proxies.","Log request ids to correlate with server-side incidents."],"tags":["mercury","edit-prediction","http","zed","status-code"],"backgroundTag":"http-error-response","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}