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

  1. Disable skipNavigation so the linkedom document (and its `body` getter) is created.
  2. Obtain the raw response text from the response object instead of `context.body`.
  3. Switch these requests to CheerioCrawler if you only need raw HTML handling.
  4. 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

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


AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30). Data as JSON: /api/errors/14552583f9aa4c5a. Report an issue: GitHub.