apify/crawlee · error · NavigationSkippedError

The `waitForSelector` method is not available - `skipNavigat

Error message

The `waitForSelector` method is not available - `skipNavigation` was used

What it means

NavigationSkippedError thrown by the getter for `waitForSelector` on the crawling context. `waitForSelector` is a browser/DOM API and meaningless without navigation, so it is disabled for `skipNavigation` requests.

Source

Thrown at packages/http-crawler/src/internals/http-crawler.ts:572

        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',
                    );
                },
            };
        }

        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)) {

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Remove `waitForSelector` calls from HTTP handlers or guard them behind `!request.skipNavigation`.
  2. Use plain parsing of `context.body` after a real navigation instead.
  3. Route skipped requests to handlers without DOM helpers.

Example fix

// before
await context.waitForSelector('.item');
// after
if (!context.request.skipNavigation) { await context.waitForSelector('.item'); }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!request.skipNavigation && typeof ctx.waitForSelector === 'function') { await ctx.waitForSelector(sel); }

Type guard

function supportsDomWait(ctx: CrawlingContext): boolean { return !(ctx.request as any).skipNavigation; }

Try / catch

try { await ctx.waitForSelector(sel); } catch (err) { if (err instanceof NavigationSkippedError) { /* skip DOM wait for HTTP-only context */ } else throw err; }

Prevention

When it happens

Trigger: Calling `context.waitForSelector(...)` in a handler for a `skipNavigation: true` request (typically in code shared with a browser crawler).

Common situations: Porting Playwright/CheerioCrawler-style handlers to HttpCrawler with skipNavigation seeds; copy-pasted handlers including DOM waits that never apply to plain HTTP.

Related errors


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