can1357/oh-my-pi · error · SearchProviderError
Anthropic API error (${response.status}): ${errorText}
Error message
Anthropic API error (${response.status}): ${errorText} What it means
The Anthropic search provider calls the Anthropic API; on a non-OK HTTP status it first tries classifyProviderHttpError to map known statuses to richer errors. If unclassified, it throws SearchProviderError carrying the raw status and response body text — the generic fallback for any API rejection (auth, rate limit, server error, malformed request).
Source
Thrown at packages/coding-agent/src/web/search/providers/anthropic.ts:220
if (systemBlocks && systemBlocks.length > 0) {
body.system = systemBlocks;
}
// OAuth requests inject the CC billing header (buildSystemBlocks); patch its
// cch attestation like the streaming path instead of shipping `cch=00000`.
const doFetch = auth.isOAuth ? wrapFetchForCch(fetchImpl) : fetchImpl;
const response = await doFetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
signal: withHardTimeout(signal, timeoutMs),
});
if (!response.ok) {
const errorText = await response.text();
const classified = classifyProviderHttpError("anthropic", response.status, errorText);
if (classified) throw classified;
throw new SearchProviderError(
"anthropic",
`Anthropic API error (${response.status}): ${errorText}`,
response.status,
);
}
return response.json() as Promise<AnthropicApiResponse>;
}
/**
* Parses a human-readable page age string into seconds.
* @param pageAge - Age string like "2 days ago", "3h ago", "1 week ago"
* @returns Age in seconds, or undefined if parsing fails
*/
function parsePageAge(pageAge: string | null | undefined): number | undefined {
if (!pageAge) return undefined;
const match = pageAge.match(/^(\d+)\s*(s|sec|second|m|min|minute|h|hour|d|day|w|week|mo|month|y|year)s?\s*(ago)?$/i);View on GitHub (pinned to 9690622007)
Solutions
- Read the embedded status and errorText to identify root cause (401 → fix key, 429 → back off, 5xx → retry later).
- Verify/rotate the Anthropic API key in auth storage.
- Catch SearchProviderError and fall back to another search provider in the chain.
- Add retry with exponential backoff for 429/5xx statuses before surfacing the failure.
Example fix
// before
const res = await runSearchQuery({ query, provider: "anthropic" }, opts);
// after
try {
return await runSearchQuery({ query, provider: "anthropic" }, opts);
} catch (e) {
if (e instanceof SearchProviderError && (e.status === 429 || (e.status ?? 500) >= 500)) {
await Bun.sleep(2000);
return await runSearchQuery({ query }, opts); // retry / fallback chain
}
throw e;
} Defensive patterns
Strategy: fallback
Validate before calling
// Pre-flight: verify credentials exist before making the call
const provider = await getSearchProvider("anthropic");
if (!(await provider.isAvailable(authStorage))) {
throw new Error("Anthropic credentials missing/invalid — configure before searching");
} Type guard
null
Try / catch
try { return await searchWith("anthropic", params); }
catch (e) {
if (e instanceof SearchProviderError && typeof e.status === "number") {
if (e.status === 429 || e.status >= 500) return await searchWithAutomatic(params); // retryable
if (e.status === 401 || e.status === 403) throw new Error("Fix Anthropic credentials");
}
throw e;
} Prevention
- Rotate and verify API keys regularly; surface 401/403 immediately to the user.
- Back off on 429/5xx with exponential retry before failing.
- Use the automatic provider chain so Anthropic outages degrade gracefully.
- Keep classifyProviderHttpError mappings current for richer, actionable errors.
When it happens
Trigger: Anthropic API returns 401/403 (bad key), 429 (rate limit), 5xx (outage), or 400 (bad request) and the error classifier doesn't produce a specialized error.
Common situations: Expired or revoked ANTHROPIC_API_KEY; account out of credits; org blocked for web search; Anthropic incident/outage; request exceeding rate limits under parallel tool calls.
Related errors
- Request was aborted.
- HTTP request failed. status=${response.status}; url=${url};
- OpenAI Files API upload failed with HTTP ${response.status}
- OpenAI Files API delete failed with HTTP ${response.status}
- ${operation} failed: ${typeof details === "string" ? details
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/a6d6a81abfa63f27.
Report an issue: GitHub.