{"record":{"id":"e2dee59f1115a411","repo":"BoundaryML/baml","slug":"request-returned-status-resp-body","errorCode":null,"errorMessage":"request returned {status}:\n{resp_body}","messagePattern":"request returned (.+?):\n(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/cli/src/api_client.rs","lineNumber":41,"sourceCode":"// pub struct GetOrCreateProjectResponse {\n//     pub single_project: Option<Project>,\n//     #[allow(dead_code)]\n//     pub first_n_projects: Vec<Project>,\n//     pub total_project_count: u64,\n// }\n\ntrait ApiResponse {\n    async fn into_result(self) -> Result<serde_json::Value>;\n}\n\nimpl ApiResponse for reqwest::Response {\n    async fn into_result(self) -> Result<serde_json::Value> {\n        let status = self.status();\n        if status.is_success() {\n            Ok(self.json().await?)\n        } else {\n            let resp_body = self.text().await?;\n            Err(anyhow::anyhow!(\"request returned {status}:\\n{resp_body}\"))\n        }\n    }\n}\n\n#[derive(Debug, Serialize)]\npub struct CreateProjectRequest {\n    /// Example: \"@boundaryml/baml\"\n    pub project_fqn: String,\n}\n\n#[derive(Debug, Deserialize)]\npub struct CreateProjectResponse {\n    pub project: Project,\n}\n\nimpl ApiClient {\n    pub async fn create_project(&self, req: CreateProjectRequest) -> Result<CreateProjectResponse> {\n        let resp = baml_runtime::request::create_client()?","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/cli/src/api_client.rs#L23-L59","documentation":"The CLI API client wraps each HTTP response in into_result: success statuses are deserialized as JSON, while any non-success status reads the body as text and returns it verbatim in an anyhow error prefixed with the status. It exists so backend error payloads (HTML or JSON error bodies) reach the CLI user directly.","triggerScenarios":"Any API call whose response status is not 2xx — 401 unauthorized, 404 project not found, 422 validation error, 5xx server error — causes into_result to bail with the status line and raw body.","commonSituations":"Expired/missing auth token (401); requesting a project or resource name that doesn't exist (404); server-side bugs or maintenance windows (500/502/503); rate limiting (429).","solutions":["Read the {status} and {resp_body} in the error: the body usually contains the server's specific error message","For 401, refresh or re-authenticate (re-login / fix API key)","For 404, verify the project/resource identifier used in the request","For 5xx, retry after a delay; check service status if persistent","For 429, apply backoff before retrying"],"exampleFix":"// before\nlet project = client.get(url).send().await?.into_result().await?;\n// after\nmatch client.get(url).send().await?.into_result().await {\n    Ok(project) => Ok(project),\n    Err(e) if e.to_string().contains(\"401\") => {\n        client.reauthenticate().await?;\n        client.get(url).send().await?.into_result().await\n    }\n    Err(e) => Err(e),\n}","handlingStrategy":"try-catch","validationCode":"if !api_token_is_set() { return Err(anyhow!(\"missing API token; run `baml-cli login` first\")); }","typeGuard":null,"tryCatchPattern":"match resp.into_result().await {\n    Ok(v) => v,\n    Err(e) if e.to_string().starts_with(\"request returned 401\") => reauth_and_retry().await,\n    Err(e) => return Err(e),\n}","preventionTips":["Check the status code and body in the error message before assuming a client bug","Refresh auth credentials when seeing 401 statuses","Add retry/backoff for 429/5xx responses","Validate resource identifiers client-side to avoid 404s"],"tags":["http","api","cli"],"backgroundTag":"http-error-response","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}