{"record":{"id":"7910c2bfccfc403e","repo":"tinyhumansai/openhuman","slug":"exa-returned-non-2xx-status-status","errorCode":null,"errorMessage":"Exa returned non-2xx status {status}","messagePattern":"Exa returned non-2xx status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/openhuman/search/tools/exa.rs","lineNumber":243,"sourceCode":"                tracing::warn!(\"[exa] request to {path} failed: {e}\");\n                anyhow::anyhow!(\"Exa request failed: {e}\")\n            })?;\n\n        let status = resp.status();\n        if !status.is_success() {\n            // Read and drop the body: Exa echoes the query back in errors and\n            // the message reaches the agent transcript.\n            let body_len = resp.text().await.unwrap_or_default().len();\n            tracing::warn!(status = %status, body_len, \"[exa] non-2xx response\");\n            if status == reqwest::StatusCode::UNAUTHORIZED\n                || status == reqwest::StatusCode::FORBIDDEN\n            {\n                anyhow::bail!(\n                    \"Exa rejected the configured API key (HTTP {status}). \\\n                     Check your Exa API key under Connections > Search engine.\"\n                );\n            }\n            anyhow::bail!(\"Exa returned non-2xx status {status}\");\n        }\n\n        resp.json().await.map_err(|e| {\n            tracing::warn!(\"[exa] failed to read response JSON: {e}\");\n            anyhow::anyhow!(\"Failed to read Exa response JSON: {e}\")\n        })\n    }\n\n    async fn post_documents(&self, path: &str, body: Value) -> anyhow::Result<Vec<ExaResultItem>> {\n        let value = self.post(path, body).await?;\n        let parsed: ExaSearchResponse = serde_json::from_value(value).map_err(|e| {\n            tracing::warn!(\"[exa] failed to parse {path} response: {e}\");\n            anyhow::anyhow!(\"Failed to parse Exa response: {e}\")\n        })?;\n        tracing::debug!(path, result_count = parsed.results.len(), \"[exa] call ok\");\n        Ok(parsed.results)\n    }\n","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/src/openhuman/search/tools/exa.rs#L225-L261","documentation":"Exa answered a non-2xx status other than the auth-rejected case — transient upstream errors, bad request shape, or rate limiting. Body is dropped to avoid leaking the echoed query.","triggerScenarios":"Thrown at src/openhuman/search/tools/exa.rs:243 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the request for 5xx/429 responses","Check request parameters for 4xx responses","Check Exa status if failures persist"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}