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
In LinkedomCrawler skipNavigation mode the `body` getter, which would normally return the parsed document HTML, is replaced by a throwing getter since no document was produced. It preserves the NavigationSkippedError as the cause for diagnosis.
Source
Thrown at packages/linkedom-crawler/src/internals/linkedom-crawler.ts:254
get body() {
return document.documentElement.outerHTML;
},
get document() {
// See comment about typing in LinkeDOMCrawlingContext definition
return document as unknown as Document;
},
};
} catch (err) {
if (err instanceof NavigationSkippedError) {
return {
get window(): Window {
throw new NavigationSkippedError(
'The `window` property is not available - `skipNavigation` was used',
{ cause: err },
);
},
get body(): string {
throw new NavigationSkippedError(
'The `body` property is not available - `skipNavigation` was used',
{ cause: err },
);
},
get document(): Document {
throw new NavigationSkippedError(
'The `document` property is not available - `skipNavigation` was used',
{ cause: err },
);
},
};
}
throw err;
}
}
private async addHelpers(crawlingContext: InternalHttpCrawlingContext & { body: string; window: Window }) {View on GitHub (pinned to dbe57fb09c)
Solutions
- Disable skipNavigation so the linkedom document (and its `body` getter) is created.
- Obtain the raw response text from the response object instead of `context.body`.
- Switch these requests to CheerioCrawler if you only need raw HTML handling.
- Guard DOM/body access with a check on whether navigation was skipped.
Example fix
// before (skipNavigation: true) const html = context.body; // throws // after const html = context.response?.body ?? ''; // raw source, not the DOM body getter
Defensive patterns
Strategy: try-catch
Validate before calling
if (request.skipNavigation === true) {
// use context.response for raw HTML; context.body getter throws
} Type guard
null
Try / catch
let html: string;
try {
html = context.body;
} catch (err) {
if ((err as Error).message.includes('`skipNavigation` was used')) {
html = await context.response.text();
} else {
throw err;
}
} Prevention
- Don't reuse JSDOMCrawler-style `context.body` assumptions in skipNavigation linkedom handlers.
- Fetch raw HTML via the response object in skipNavigation mode.
- Prefer CheerioCrawler when raw HTML access is the primary need.
- Note the skipNavigation contract in team docs: no window/body/document getters.
When it happens
Trigger: Reading `context.body` in a LinkedomCrawler requestHandler for a request run with `skipNavigation: true`.
Common situations: Handlers written for the default (parsing) mode reused on skipNavigation crawls; confusion with CheerioCrawler, where `context.body` is always the raw HTML string.
Related errors
- The `window` property is not available - `skipNavigation` wa
- The `document` property is not available - `skipNavigation`
- The `window` property is not available - `skipNavigation` wa
- The `body` property is not available - `skipNavigation` was
- The `document` property is not available - `skipNavigation`
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/14552583f9aa4c5a.
Report an issue: GitHub.