can1357/oh-my-pi · error · SearchProviderError
Perplexity ask API error (${response.status}): ${errorText}
Error message
Perplexity ask API error (${response.status}): ${errorText} What it means
The Perplexity ask (OAuth/cookie) endpoint returned a non-ok HTTP response. The body text is captured, offered to classifyProviderHttpError, and otherwise thrown as a SearchProviderError including the response status and the raw error body.
Source
Thrown at packages/coding-agent/src/web/search/providers/perplexity.ts:729
};
// The consumer ask endpoint intermittently drops the socket before sending an
// HTTP response (#5315). Retry the transport exactly once; once we hold an
// HTTP response (handled below) the outcome — including non-2xx — is final and
// never retried, so a real 401/429 is never papered over by a second attempt.
let response: Response;
try {
response = await (params.fetch ?? fetch)(PERPLEXITY_OAUTH_ASK_URL, requestInit);
} catch (error) {
if (params.signal?.aborted) throw error;
response = await (params.fetch ?? fetch)(PERPLEXITY_OAUTH_ASK_URL, requestInit);
}
if (!response.ok) {
const errorText = await response.text();
const classified = classifyProviderHttpError("perplexity", response.status, errorText);
if (classified) throw classified;
throw new SearchProviderError(
"perplexity",
`Perplexity ask API error (${response.status}): ${errorText}`,
response.status,
);
}
if (!response.body) {
throw new SearchProviderError("perplexity", "Perplexity ask API returned no response body", 500);
}
let answer = "";
let model: string | undefined;
let finalRequestId: string | undefined;
const sourcesByUrl = new Map<string, SearchSource>();
let mergedEvent: PerplexityOAuthStreamEvent = { blocks: [] };
for await (const event of readSseJson<PerplexityOAuthStreamEvent>(response.body, params.signal)) {
if (event.error_code) {View on GitHub (pinned to 9690622007)
Solutions
- Inspect response.status embedded in the message; 401/403 -> re-authenticate (refresh OAuth token or provide cookies)
- If 429, back off and retry later
- If 5xx, retry after a delay or check Perplexity status
- Fall back to a different search provider for this query
Defensive patterns
Strategy: retry
Validate before calling
// ensure an auth path exists before calling const hasAuth = Boolean(process.env.PERPLEXITY_API_KEY) || hasStoredOAuthSession();
Type guard
function isSearchProviderError(e: unknown): e is SearchProviderError {
return e instanceof SearchProviderError;
} Try / catch
try {
return await perplexityAsk(params);
} catch (err) {
if (err instanceof SearchProviderError && /status (401|403)/.test(err.message)) {
await refreshOAuthSession(); // re-authenticate once, then retry
}
throw err;
} Prevention
- Refresh OAuth tokens proactively before expiry
- Back off on 429 instead of hammering the endpoint
- Monitor Perplexity status for 5xx windows
When it happens
Trigger: callPerplexityAsk's fetch of the ask API returns response.ok === false — e.g. expired OAuth access token (401), CSRF/cookie failure (403), rate limiting (429), or Perplexity server errors (5xx).
Common situations: Stale or revoked Perplexity OAuth session, anonymous-mode IP blocked/challenged by Perplexity, per-account rate limits, Perplexity outages.
Related errors
- Perplexity API error (${status}): ${details}
- Failed to create Smithery auth session: ${response.status} $
- Smithery auth polling failed: ${response.status} ${response.
- parallel: err.message (dynamic; thrown as SearchProviderErro
- Perplexity ask stream error: ${message}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3505aa463c821127.
Report an issue: GitHub.