can1357/oh-my-pi · error · SearchProviderError

Exa MCP request failed

Error message

Exa MCP request failed (${response.status}): ${errorText}

What it means

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.

Solutions

  1. Read the status and embedded errorText to identify the failure.
  2. Retry with backoff for 5xx (transient gateway/service errors).
  3. Check Exa status page for ongoing incidents.
  4. Configure an API key and use the REST path if the MCP endpoint is persistently failing.
Defensive patterns

Strategy: retry

Try / catch

try {
  const res = await searchExa({ query });
} catch (e) {
  if (e instanceof SearchProviderError && e.status >= 500) {
    await Bun.sleep(2000); // transient MCP gateway errors usually clear
  } else throw e;
}

Prevention

When it happens

Trigger: callExaMcpSearch request failing with statuses like 400, 401, 500, 502, 503 from the MCP endpoint; classifyProviderHttpError returned no specific error and status !== 429.

Common situations: Exa MCP service outage (5xx); request rejected due to malformed payload (400); proxy/gateway errors between the client and Exa.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/9b6003e055f796ba. Report an issue: GitHub.

Appendix: source

Thrown at packages/coding-agent/src/web/search/providers/exa.ts:388

			params: {
				name: "web_search_exa",
				arguments: buildExaMcpArgs(params),
			},
		}),
		signal: withHardTimeout(params.signal, params.timeoutMs),
	});
	if (!response.ok) {
		const errorText = await response.text();
		const classified = classifyProviderHttpError("exa", response.status, errorText);
		if (classified) throw classified;
		if (response.status === 429) {
			throw new SearchProviderError(
				"exa",
				"exa: MCP rate limit reached (429); configure an Exa API key for higher limits",
				response.status,
			);
		}
		throw new SearchProviderError(
			"exa",
			`Exa MCP request failed (${response.status}): ${errorText}`,
			response.status,
		);
	}
	const mcpResponse = parseSSE(await response.text()) as {
		result?: {
			content?: Array<{ type: string; text?: string }>;
			isError?: boolean;
		};
		error?: {
			code: number;
			message: string;
		};
	} | null;
	if (!mcpResponse) {
		throw new Error("Failed to parse MCP response");
	}

View on GitHub (pinned to 9690622007)