{"record":{"id":"9b6003e055f796ba","repo":"can1357/oh-my-pi","slug":"exa-mcp-request-failed-response-status-err","errorCode":null,"errorMessage":"Exa MCP request failed (${response.status}): ${errorText}","messagePattern":"Exa MCP request failed \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"SearchProviderError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/web/search/providers/exa.ts","lineNumber":388,"sourceCode":"\t\t\tparams: {\n\t\t\t\tname: \"web_search_exa\",\n\t\t\t\targuments: buildExaMcpArgs(params),\n\t\t\t},\n\t\t}),\n\t\tsignal: withHardTimeout(params.signal, params.timeoutMs),\n\t});\n\tif (!response.ok) {\n\t\tconst errorText = await response.text();\n\t\tconst classified = classifyProviderHttpError(\"exa\", response.status, errorText);\n\t\tif (classified) throw classified;\n\t\tif (response.status === 429) {\n\t\t\tthrow new SearchProviderError(\n\t\t\t\t\"exa\",\n\t\t\t\t\"exa: MCP rate limit reached (429); configure an Exa API key for higher limits\",\n\t\t\t\tresponse.status,\n\t\t\t);\n\t\t}\n\t\tthrow new SearchProviderError(\n\t\t\t\"exa\",\n\t\t\t`Exa MCP request failed (${response.status}): ${errorText}`,\n\t\t\tresponse.status,\n\t\t);\n\t}\n\tconst mcpResponse = parseSSE(await response.text()) as {\n\t\tresult?: {\n\t\t\tcontent?: Array<{ type: string; text?: string }>;\n\t\t\tisError?: boolean;\n\t\t};\n\t\terror?: {\n\t\t\tcode: number;\n\t\t\tmessage: string;\n\t\t};\n\t} | null;\n\tif (!mcpResponse) {\n\t\tthrow new Error(\"Failed to parse MCP response\");\n\t}","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/web/search/providers/exa.ts#L370-L406","documentation":"The Exa MCP endpoint returned a non-2xx HTTP status that was neither classified nor a 429. The provider throws SearchProviderError with the status and the raw response body text embedded in the message.","triggerScenarios":"callExaMcpSearch request failing with statuses like 400, 401, 500, 502, 503 from the MCP endpoint; classifyProviderHttpError returned no specific error and status !== 429.","commonSituations":"Exa MCP service outage (5xx); request rejected due to malformed payload (400); proxy/gateway errors between the client and Exa.","solutions":["Read the status and embedded errorText to identify the failure.","Retry with backoff for 5xx (transient gateway/service errors).","Check Exa status page for ongoing incidents.","Configure an API key and use the REST path if the MCP endpoint is persistently failing."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const res = await searchExa({ query });\n} catch (e) {\n  if (e instanceof SearchProviderError && e.status >= 500) {\n    await Bun.sleep(2000); // transient MCP gateway errors usually clear\n  } else throw e;\n}","preventionTips":["Retry 5xx with backoff; do not retry 4xx","Watch Exa's status page for MCP incidents","Keep the REST API (API key) path as a fallback","Log the embedded errorText to distinguish gateway vs application errors"],"tags":["http","mcp","exa","search-provider"],"backgroundTag":"http-5xx-server-error","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}