{"record":{"id":"f35032d9e18073f8","repo":"zed-industries/zed","slug":"failed-to-fetch-url-status-code-f35032","errorCode":null,"errorMessage":"failed to fetch '{url}': status code {}","messagePattern":"failed to fetch '(.+?)': status code (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/extension_host/src/wasm_host/wit/since_v0_8_0.rs","lineNumber":639,"sourceCode":"        let delegate = self.table.get(&delegate)?;\n        Ok(delegate.which(binary_name).await)\n    }\n\n    async fn drop(&mut self, _worktree: Resource<Worktree>) -> wasmtime::Result<()> {\n        // We only ever hand out borrows of worktrees.\n        Ok(())\n    }\n}\n\nimpl common::Host for WasmState {}\n\nimpl http_client::Host for WasmState {\n    async fn fetch(\n        &mut self,\n        request: http_client::HttpRequest,\n    ) -> wasmtime::Result<Result<http_client::HttpResponse, String>> {\n        maybe!(async {\n            let url = &request.url;\n            let request = convert_request(&request)?;\n            let mut response = self.host.http_client.send(request).await?;\n\n            if response.status().is_client_error() || response.status().is_server_error() {\n                bail!(\"failed to fetch '{url}': status code {}\", response.status())\n            }\n            convert_response(&mut response).await\n        })\n        .await\n        .to_wasmtime_result()\n    }\n\n    async fn fetch_stream(\n        &mut self,\n        request: http_client::HttpRequest,\n    ) -> wasmtime::Result<Result<Resource<ExtensionHttpResponseStream>, String>> {\n        let request = convert_request(&request).into_wasmtime_result()?;\n        let response = self.host.http_client.send(request);","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/zed-industries/zed/blob/5a9b9558db01a6b906cec2fb70a797affdc58cdd/crates/extension_host/src/wasm_host/wit/since_v0_8_0.rs#L621-L657","documentation":"Same guard as in the v0.1.0 bindings, present in the v0.8.0 host: http_client::fetch bails whenever the response status is a client or server error, embedding the requested URL and the status. The v0.8.0 fetch, like v0.1.0, returns Ok(HttpResponse) only for 2xx/3xx; the error string is surfaced to the extension as the Err side of its Result. fetch_stream remains the escape hatch for reading non-2xx bodies.","triggerScenarios":"An extension on the v0.8.0 API calling http_client::fetch against any URL returning 4xx/5xx (404 release asset, 403 rate-limited API, 500 server error).","commonSituations":"Download URLs that 404 after an upstream release rename, GitHub API secondary rate limits returning 403, expired tokens, or corporate proxies answering 502.","solutions":["curl -I the exact URL from the message to see the real status and act on it (fix URL, add auth header, wait out rate limit)","Switch to fetch_stream when the error body or status must be inspected","Add retry with backoff for 5xx/429 responses","Cache downloaded assets so transient failures degrade gracefully"],"exampleFix":"// before\nlet response = http_client::fetch(&request).await?; // Err(\"failed to fetch '...': status code 403 Forbidden\")\n\n// after\nmatch http_client::fetch(&request).await {\n    Ok(response) => Ok(response),\n    Err(e) if e.contains(\"status code 4\") || e.contains(\"status code 5\") => {\n        Err(format!(\"download failed ({e}); check URL/auth\"))\n    }\n    Err(e) => Err(e),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match http_client::fetch(&request).await {\n    Ok(response) => Ok(response),\n    Err(e) if e.contains(\"status code 4\") || e.contains(\"status code 5\") => {\n        Err(format!(\"non-2xx response: {e}\"))\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Validate/normalize URLs before fetching (no trailing spaces, correct release tag)","Attach auth headers up front for private resources instead of discovering 401/403 at runtime","Use fetch_stream when status or error body matters"],"tags":["network","http","wasm","extension","zed"],"backgroundTag":"http-error-status","analyzedSha":"5a9b9558db01a6b906cec2fb70a797affdc58cdd","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}