{"record":{"id":"39a425900d666016","repo":"apify/crawlee","slug":"selector-selector-not-found","errorCode":null,"errorMessage":"Selector '${selector}' not found.","messagePattern":"Selector '(.+?)' not found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cheerio-crawler/src/internals/cheerio-crawler.ts","lineNumber":301,"sourceCode":"            enqueueLinks: async (options: EnqueueLinksOptions = {}) => {\n                const baseUrl = resolveBaseUrlForEnqueueLinksFiltering({\n                    enqueueStrategy: options.strategy,\n                    finalRequestUrl: crawlingContext.request.loadedUrl,\n                    originalRequestUrl: crawlingContext.request.url,\n                    userProvidedBaseUrl: options.baseUrl,\n                });\n\n                const urls = await extractLinks(options);\n\n                return addRequests(urls, {\n                    ...options,\n                    baseUrl,\n                    strategy: options.strategy ?? EnqueueStrategy.SameHostname,\n                });\n            },\n            waitForSelector: async (selector: string, _timeoutMs?: number) => {\n                if (crawlingContext.$(selector).get().length === 0) {\n                    throw new Error(`Selector '${selector}' not found.`);\n                }\n            },\n            parseWithCheerio: async (selector?: string, timeoutMs?: number) => {\n                if (selector) {\n                    await crawlingContext.waitForSelector(selector, timeoutMs);\n                }\n\n                return crawlingContext.$;\n            },\n        };\n    }\n}\n\n/**\n * Creates new {@apilink Router} instance that works based on request labels.\n * This instance can then serve as a `requestHandler` of your {@apilink CheerioCrawler}.\n * Defaults to the {@apilink CheerioCrawlingContext}.\n *","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/cheerio-crawler/src/internals/cheerio-crawler.ts#L283-L319","documentation":"CheerioCrawler's `waitForSelector` helper is synchronous over the already-parsed Cheerio document; it cannot wait. If the selector matches zero elements at call time it throws 'Selector not found', unlike browser-based crawlers where it would poll until timeout.","triggerScenarios":"Calling `waitForSelector(selector)` (directly or via `parseWithCheerio(selector)`) when the loaded page's Cheerio DOM contains no elements matching the selector.","commonSituations":"Porting code from PlaywrightCrawler/PuppeteerCrawler where waitForSelector waits for dynamically injected content; typos in selectors; content rendered client-side that Cheerio's static HTML never sees.","solutions":["Fix the selector or verify the element truly exists in the served HTML.","Remove waitForSelector calls in CheerioCrawler — it does not wait; the document is already fully parsed.","If content is client-rendered, switch to PlaywrightCrawler/PuppeteerCrawler.","Check `$(selector).length` yourself before calling to avoid the throw."],"exampleFix":"// before\nawait context.waitForSelector('div.results');\n// after\nif (context.$('div.results').length === 0) { log.warning('no results in static HTML'); } else { await context.parseWithCheerio('div.results'); }","handlingStrategy":"validation","validationCode":"if (context.$('div.results').length === 0) { log.warning('selector missing in static HTML'); return; }","typeGuard":"function selectorExists(ctx: { $: CheerioAPI }, selector: string): boolean { return ctx.$(selector).length > 0; }","tryCatchPattern":"try { await context.waitForSelector(sel); } catch (err) { if (err.message.startsWith(\"Selector '\")) { /* static HTML lacks element */ } else { throw err; } }","preventionTips":["Remember CheerioCrawler's waitForSelector never waits — remove such calls when porting from browser crawlers","Inspect the served HTML to confirm selectors match server-rendered content","Use PlaywrightCrawler for client-rendered content"],"tags":["cheerio-crawler","selector","api-differences"],"backgroundTag":"selector-not-found","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}