apify/crawlee · error · NavigationSkippedError
The `parseWithCheerio` method is not available - `skipNaviga
Error message
The `parseWithCheerio` method is not available - `skipNavigation` was used
What it means
NavigationSkippedError thrown by the getter for `parseWithCheerio` on the crawling context. Without navigation there is no HTML document, so cheerio parsing is unavailable and access throws immediately.
Source
Thrown at packages/http-crawler/src/internals/http-crawler.ts:577
);
},
get body(): InternalHttpCrawlingContext['body'] {
throw new NavigationSkippedError(
'The `body` property is not available - `skipNavigation` was used',
);
},
get json(): InternalHttpCrawlingContext['json'] {
throw new NavigationSkippedError(
'The `json` property is not available - `skipNavigation` was used',
);
},
get waitForSelector(): InternalHttpCrawlingContext['waitForSelector'] {
throw new NavigationSkippedError(
'The `waitForSelector` method is not available - `skipNavigation` was used',
);
},
get parseWithCheerio(): InternalHttpCrawlingContext['parseWithCheerio'] {
throw new NavigationSkippedError(
'The `parseWithCheerio` method is not available - `skipNavigation` was used',
);
},
};
}
tryCancel();
// Before `parseResponse`, which throws for error status codes - a 429 the user opted into treating as an
// error is still a rate limit the domain should back off from.
if (crawlingContext.response.status === 429) {
const retryAfter = crawlingContext.response.headers.get('retry-after');
if (this.recordDomainRateLimit(crawlingContext.request.url, retryAfter)) {
// This is the one path that never reads the body, so cancel it to release the connection
// rather than leaving it to the garbage collector.
await crawlingContext.response.body?.cancel().catch(() => {});
throw new RequestThrottledError(`${crawlingContext.request.url} responded with 429.`);
}View on GitHub (pinned to dbe57fb09c)
Solutions
- Guard `parseWithCheerio` behind `!context.request.skipNavigation`.
- Parse HTML only in handlers that follow a real navigation; use `userData` payloads for skipped requests.
- Route skipNavigation requests via labels to a non-parsing handler.
Example fix
// before
const $ = await context.parseWithCheerio();
// after
if (context.request.skipNavigation) { return; }
const $ = await context.parseWithCheerio(); Defensive patterns
Strategy: type-guard
Validate before calling
if (request.skipNavigation) { return; }
const $ = await ctx.parseWithCheerio(); Type guard
function canParse(ctx: CrawlingContext): boolean { return !(ctx.request as any).skipNavigation; } Try / catch
try { const $ = await ctx.parseWithCheerio(); } catch (err) { if (err instanceof NavigationSkippedError) { return; /* nothing to parse */ } throw err; } Prevention
- Early-return before parsing when skipNavigation.
- Only call parseWithCheerio in handlers that follow navigation.
- Dedicated seed handlers that enqueue and return.
- Lint for unconditional parseWithCheerio in shared code.
When it happens
Trigger: Calling `const $ = await context.parseWithCheerio()` in a request handler for a `skipNavigation: true` request.
Common situations: Standard scraping handlers applied to seed requests; helpers that unconditionally parse HTML from every context.
Related errors
- The `request.loadedUrl` property is not available - `skipNav
- The `response` property is not available - `skipNavigation`
- The `contentType` property is not available - `skipNavigatio
- The `body` property is not available - `skipNavigation` was
- The `json` property is not available - `skipNavigation` was
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/fe217cd892a5e6fc.
Report an issue: GitHub.