apify/crawlee · error · NavigationSkippedError
The `body` property is not available - `skipNavigation` was
Error message
The `body` property is not available - `skipNavigation` was used
What it means
NavigationSkippedError thrown by the getter for `body` on the crawling context. `skipNavigation` requests have no downloaded body, so accessing `context.body` throws instead of returning `undefined` and masking the cause.
Source
Thrown at packages/http-crawler/src/internals/http-crawler.ts:562
request.state = RequestState.AFTER_NAV;
return { request: request as LoadedRequest<CrawleeRequest>, response: httpResponse };
}
private async processHttpResponse(
crawlingContext: CrawlingContextWithResponse,
): Promise<
Omit<InternalHttpCrawlingContext, keyof CrawlingContextWithResponse> & Partial<InternalHttpCrawlingContext>
> {
if (crawlingContext.request.skipNavigation) {
return {
get contentType(): InternalHttpCrawlingContext['contentType'] {
throw new NavigationSkippedError(
'The `contentType` property is not available - `skipNavigation` was used',
);
},
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',
);
},View on GitHub (pinned to dbe57fb09c)
Solutions
- Guard with `if (!context.request.skipNavigation)` before reading `body`.
- Store any needed payload on the request's `userData` when queueing a skipNavigation request.
- Split handler logic so skipNavigation requests never reach body-parsing code.
Example fix
// before
const $ = cheerio.load(context.body);
// after
if (!context.request.skipNavigation) { const $ = cheerio.load(context.body); } else { handleSeed(context.request); } Defensive patterns
Strategy: type-guard
Validate before calling
if (request.skipNavigation) { return; } // never read body Type guard
function hasBody(ctx: CrawlingContext): boolean { return !(ctx.request as any).skipNavigation; } Try / catch
try { const body = ctx.body; } catch (err) { if (err instanceof NavigationSkippedError) { /* use userData payload instead */ } else throw err; } Prevention
- Early-return when skipNavigation is set.
- Attach payloads via request.userData for skipped requests.
- Never pass ctx.body blindly to cheerio/parsers.
- Split fetch-handlers from seed-handlers.
When it happens
Trigger: Accessing `context.body` in a request handler for a request queued with `skipNavigation: true`.
Common situations: Handlers that always call `context.body` or pass it to parsers/cheerio; migrating handlers from normal requests to seeded skipNavigation entries.
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 `json` property is not available - `skipNavigation` was
- The `waitForSelector` method is not available - `skipNavigat
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/f33b55b4c03dc139.
Report an issue: GitHub.