koala73/worldmonitor · error
P0 scrape failed: HTTP ${resp.status}
Error message
P0 scrape failed: HTTP ${resp.status} What it means
P0Provider.fetch() throws when POST {P0_BASE_URL}/scrape (default https://api.parallelai.dev/v1/scrape) returns a non-2xx status. P0 is the JS-rendering, anti-bot, premium-proxy scraping provider; the request sends x-api-key auth with render_js:true, premium_proxy:true, and an AbortSignal deadline 10s above the render budget. Any HTTP-level rejection — bad key, quota, malformed body, provider outage — surfaces here with the raw status code.
Source
Thrown at consumer-prices-core/src/acquisition/p0.ts:54
};
}
async fetch(url: string, opts: FetchOptions = {}): Promise<FetchResult> {
const resp = await fetch(`${this.baseUrl}/scrape`, {
method: 'POST',
headers: this.headers(),
body: JSON.stringify({
url,
render_js: true,
wait_for: opts.waitForSelector,
timeout: Math.floor((opts.timeout ?? 30_000) / 1_000),
output_format: 'html',
premium_proxy: true,
}),
signal: AbortSignal.timeout((opts.timeout ?? 30_000) + 10_000),
});
if (!resp.ok) throw new Error(`P0 scrape failed: HTTP ${resp.status}`);
const data = (await resp.json()) as P0ScrapeResponse;
if (!data.success && !data.html) {
throw new Error(`P0 error: ${data.error ?? 'no content'}`);
}
return {
url,
html: data.html ?? '',
markdown: data.markdown,
statusCode: data.statusCode ?? 200,
provider: this.name,
fetchedAt: new Date(),
};
}
async search(query: string, opts: SearchOptions = {}): Promise<SearchResult[]> {
const resp = await fetch(`${this.baseUrl}/search`, {View on GitHub (pinned to eeab0a219f)
Solutions
- Map the status: 401/403 fix P0_API_KEY, 402/429 check plan/quota, 5xx retry later
- Set acquisition.fallback (e.g. 'playwright' or 'firecrawl') in the retailer config so fetchWithFallback absorbs the failure
- Verify P0_BASE_URL resolves to the intended environment and API version
- Confirm the timeout budget (opts.timeout, sent as floor(ms/1000) seconds) is within what the plan allows
Example fix
// before — single provider, one HTTP failure kills the target
const r = await getProvider('p0').fetch(url);
// after — declare a fallback chain in the retailer acquisition config
const acquisition = { provider: 'p0', fallback: 'playwright', options: { waitForSelector: '.price' } };
const r = await fetchWithFallback(url, acquisition); Defensive patterns
Strategy: fallback
Validate before calling
// fail fast before the run: provider reachable?
if (!(await getProvider('p0').validate())) { // GET /health
throw new Error('P0 unavailable — configure acquisition.fallback before scraping');
} Type guard
function isP0HttpError(err: unknown): boolean {
return err instanceof Error && /^P0 scrape failed: HTTP \d+$/.test(err.message);
} Try / catch
try {
return await p0.fetch(url, opts);
} catch (err) {
if (isP0HttpError(err)) {
return await getProvider('playwright').fetch(url, opts); // mirror registry.fetchWithFallback
}
throw err;
} Prevention
- Always configure acquisition.fallback for P0-backed retailers — fetchWithFallback exists for exactly this shape
- Run P0Provider.validate() (GET /health) at startup and drop P0 from the chain when it fails
- Keep P0_API_KEY and P0_BASE_URL in one env source so they rotate together
When it happens
Trigger: 401/403 with an invalid or revoked P0_API_KEY; 402/429 when the plan is exhausted or rate-limited; 4xx for a scrape body P0 rejects; 5xx during a P0 outage; P0_BASE_URL pointing at the wrong host or path so every call hits a gateway error.
Common situations: P0_API_KEY rotated or expired so every scrape in a retailer run 401s; a new environment pointing P0_BASE_URL at a different stage; rate limits hit because render_js + premium_proxy calls are expensive per request; registry.fetchWithFallback logs '[acquisition] p0 failed ... Falling back to ...' and this error re-throws only when no fallback is configured.
Related errors
- Firecrawl extract error: ${data.error ?? 'unknown'}
- P0 search failed: HTTP ${resp.status}
- P0 error: ${data.error ?? 'no content'}
- Revoke failed (HTTP ${resp.status}).
- DNS ${recordType} lookup failed: status ${data.Status}
AI-assisted analysis of koala73/worldmonitor@eeab0a219f (2026-08-21).
Data as JSON: /api/errors/07c7b91bf137004e.
Report an issue: GitHub.