{"record":{"id":"1b0758000b8d3e98","repo":"windmill-labs/windmill","slug":"http-agent-request-get-failed","errorCode":null,"errorMessage":"HTTP agent request GET {} failed {}","messagePattern":"HTTP agent request GET (.+?) failed (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-common/src/worker.rs","lineNumber":603,"sourceCode":"                url,\n                response.status()\n            )))\n        }\n    }\n\n    pub async fn get<R: DeserializeOwned>(&self, url: &str) -> anyhow::Result<R> {\n        let base_url = self.base_internal_url.clone();\n        let response = self\n            .client\n            .get(format!(\"{}{}\", base_url, url))\n            .send()\n            .await\n            .map_err(|e| anyhow::anyhow!(e))?;\n        let status = response.status();\n        if status.is_success() {\n            Ok(response.json().await?)\n        } else {\n            Err(anyhow::anyhow!(format!(\n                \"HTTP agent request GET {} failed {}\",\n                url,\n                response.status()\n            )))\n        }\n    }\n\n    pub async fn get_bytes(&self, url: &str) -> anyhow::Result<Bytes> {\n        let base_url = self.base_internal_url.clone();\n        let response = self\n            .client\n            .get(format!(\"{}{}\", base_url, url))\n            .send()\n            .await\n            .map_err(|e| anyhow::anyhow!(e))?;\n        if response.status().is_success() {\n            Ok(response.bytes().await?)\n        } else {","sourceCodeStart":585,"sourceCodeEnd":621,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-common/src/worker.rs#L585-L621","documentation":"Raised by HttpClient::get when a worker's HTTP-agent GET request returns a non-2xx status. Called by get_ducklake_from_agent_http and get_datatable_resource_from_agent_http, so in practice it usually means a datatable/ducklake resource fetch failed. Like the POST variant, the response body carrying the precise server-side reason is dropped.","triggerScenarios":"Worker calls HttpClient::get for a datatable or ducklake resource (via the agent HTTP path) and the server replies 404 (resource/table not found), 403 (insufficient permissions), 4xx (bad request), or 5xx (server error).","commonSituations":"Referenced datatable/ducklake doesn't exist or was deleted; worker token can't read the resource in that workspace; server feature not compiled/enabled; wrong base_internal_url; transient 5xx while the backend restarts.","solutions":["Check server logs for the corresponding GET request to see the discarded error body.","Verify the datatable/ducklake resource exists in the target workspace.","Check the worker's token permissions for the workspace/resource.","Retry on 5xx; fix the resource name/permissions for 4xx."],"exampleFix":"// before\nlet resource = client.get::<DatatableResource>(&url).await?;\n// after\nlet resource: DatatableResource = match client.get::<DatatableResource>(&url).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"503\") || e.to_string().contains(\"500\") => {\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        client.get::<DatatableResource>(&url).await?\n    }\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":"// Verify the resource exists before fetching\nlet exists: bool = client.get::<serde_json::Value>(\"/w/{ws}/datatables/list\")\n    .await\n    .map(|v| v.to_string().contains(&table_name))\n    .unwrap_or(false);\nif !exists {\n    return Err(anyhow::anyhow!(\"datatable '{table_name}' not found before GET\"));\n}","typeGuard":null,"tryCatchPattern":"match client.get::<R>(&url).await {\n    Ok(r) => r,\n    Err(e) if e.to_string().contains(\"404\") => {\n        return Err(anyhow::anyhow!(\"resource missing, aborting (do not retry 404): {e}\"));\n    }\n    Err(e) if e.to_string().contains(\"503\") || e.to_string().contains(\"500\") => {\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        client.get::<R>(&url).await?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Check that referenced datatables/ducklake resources exist before dispatching jobs.","Test worker token read access to the workspace resource out-of-band.","Retry only on 5xx; treat 404/403 as configuration errors to fix.","Keep backend logs accessible to correlate the status code with the real error body.","Confirm the target instance has the datatable feature compiled/enabled."],"tags":["http","network","worker","rust"],"backgroundTag":"http-non-2xx-response","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}