{"record":{"id":"c39c5e5aee160579","repo":"apify/crawlee","slug":"the-property-is-not-available-skipnavigatio","errorCode":null,"errorMessage":"The `$` property is not available - `skipNavigation` was used","messagePattern":"The `\\$` property is not available - `skipNavigation` was used","errorType":"exception","errorClass":"NavigationSkippedError","httpStatus":null,"severity":"error","filePath":"packages/cheerio-crawler/src/internals/cheerio-crawler.ts","lineNumber":254,"sourceCode":"            const $ = cheerio.load(dom, {\n                xml: { decodeEntities: true, xmlMode: isXml },\n            } as CheerioOptions);\n\n            return {\n                $,\n                body,\n            };\n        } catch (err) {\n            if (err instanceof NavigationSkippedError) {\n                return {\n                    get body(): string {\n                        throw new NavigationSkippedError(\n                            'The `body` property is not available - `skipNavigation` was used',\n                            { cause: err },\n                        );\n                    },\n                    get $(): CheerioAPI {\n                        throw new NavigationSkippedError(\n                            'The `$` property is not available - `skipNavigation` was used',\n                            { cause: err },\n                        );\n                    },\n                };\n            }\n\n            throw err;\n        }\n    }\n\n    private async addHelpers(crawlingContext: InternalHttpCrawlingContext & { $: CheerioAPI }) {\n        const addRequests = crawlingContext.addRequests;\n\n        const extractLinks = async (options?: ExtractLinksOptions): Promise<string[]> => {\n            if (!crawlingContext.$) {\n                throw new Error('Cannot extract links because the DOM is not available.');\n            }","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/cheerio-crawler/src/internals/cheerio-crawler.ts#L236-L272","documentation":"Same mechanism as `body`: with `skipNavigation` used, the response is not parsed, so the `$` (CheerioAPI) property is a getter that throws NavigationSkippedError. Crawlee throws instead of returning a broken/undefined parser so the mistake fails loudly.","triggerScenarios":"Accessing `crawlingContext.$` (or destructuring it) in a requestHandler while `skipNavigation: true` is set on the CheerioCrawler or the specific request.","commonSituations":"Using `$('a').each(...)` or `enqueueLinks` style logic in a handler after enabling skipNavigation; shared request handler reused by both a parsing crawler and a navigation-only crawler.","solutions":["Remove all `$(...)` usage from handlers running with skipNavigation.","Disable `skipNavigation` if DOM parsing is required.","Branch inside the handler on the crawler configuration instead of touching `$` unconditionally."],"exampleFix":"// before\nnew CheerioCrawler({ skipNavigation: true, requestHandler: async ({ $ }) => { await $('h1').text(); } });\n// after\nnew CheerioCrawler({ skipNavigation: true, requestHandler: async ({ request }) => { log.info(request.url); } });","handlingStrategy":"validation","validationCode":"if (crawlerOptions.skipNavigation && handlerSource.includes('$(')) { throw new Error('handler uses $ but skipNavigation is enabled'); }","typeGuard":"function hasCheerio(ctx: CrawlingContext): ctx is CrawlingContext & { $: CheerioAPI } { return (ctx as any).$ !== undefined; }","tryCatchPattern":"try { const text = context.$('h1').text(); } catch (err) { if (err instanceof NavigationSkippedError) { log.info('no DOM, skipping parse'); } else { throw err; } }","preventionTips":["Grep handlers for `$(` when toggling skipNavigation on","Type handlers narrowly so $ is not in the context type when skipNavigation is set","Use PlaywrightCrawler when DOM access is required"],"tags":["cheerio-crawler","skip-navigation","api-misuse"],"backgroundTag":"property-unavailable-when-option-disabled","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}