{"record":{"id":"25308b295eb4b6dc","repo":"jackwener/OpenCLI","slug":"indeed-served-a-cloudflare-challenge-page","errorCode":null,"errorMessage":"Indeed served a Cloudflare challenge page","messagePattern":"Indeed served a Cloudflare challenge page","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/indeed/job.js","lineNumber":66,"sourceCode":"                const notFound = !!document.querySelector('[data-testid=\"error-page\"]') || /Page Not Found|not found/i.test(document.querySelector('h1')?.textContent || '');\n                const title = document.querySelector('h1')?.textContent?.trim() ?? '';\n                const company = document.querySelector('[data-testid=\"inlineHeader-companyName\"] a, [data-testid=\"inlineHeader-companyName\"], [data-company-name=\"true\"]')?.textContent?.trim() ?? '';\n                const location = document.querySelector('[data-testid=\"jobsearch-JobInfoHeader-companyLocation\"] div, [data-testid=\"inlineHeader-companyLocation\"]')?.textContent?.trim() ?? '';\n                const salary = document.querySelector('[id*=\"salaryInfoAndJobType\"] span, [data-testid=\"job-salary\"]')?.textContent?.trim() ?? '';\n                const jobType = Array.from(document.querySelectorAll('[id*=\"salaryInfoAndJobType\"] span, [data-testid=\"job-type\"]'))\n                    .map(s => (s.textContent || '').trim())\n                    .filter(t => t && t !== salary)\n                    .join(', ');\n                const description = document.querySelector('#jobDescriptionText')?.innerText?.trim() ?? '';\n                return { ready, challenge, notFound, title, company, location, salary, jobType, description };\n            })()`);\n        }\n        catch (e) {\n            throw new CommandExecutionError(`Failed to scrape Indeed job detail DOM: ${e?.message ?? e}`, 'The page may not have fully loaded; try again.');\n        }\n\n        if (detail?.challenge) {\n            throw new CommandExecutionError('Indeed served a Cloudflare challenge page', 'Open https://www.indeed.com in the connected browser and clear the challenge, then retry.');\n        }\n        if (!detail?.ready) {\n            throw new CommandExecutionError('Indeed job page did not expose detail or error markers within 15s', 'Indeed may still be loading or the DOM shape may have changed; retry after opening Indeed in the connected browser.');\n        }\n        if (detail?.notFound || (!detail?.title && !detail?.description)) {\n            throw new EmptyResultError('indeed job', `No Indeed job posting found for jk \"${jk}\"`);\n        }\n\n        return [{\n            id: jk,\n            title: detail.title.replace(/\\s+/g, ' ').trim(),\n            company: detail.company.replace(/\\s+/g, ' ').trim(),\n            location: detail.location.replace(/\\s+/g, ' ').trim(),\n            salary: detail.salary.replace(/\\s+/g, ' ').trim(),\n            job_type: detail.jobType.replace(/\\s+/g, ' ').trim(),\n            description: detail.description,\n            url,\n        }];","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/indeed/job.js#L48-L84","documentation":"Thrown when the scraped job detail page is detected as a Cloudflare challenge: document.title contains 'Just a moment' or an element matching [id^=\"cf-\"] is present. Indeed shields itself with Cloudflare and the CLI cannot (and will not) bypass it.","triggerScenarios":"detail.challenge is true after evaluating the job page DOM, i.e. headline includes 'Just a moment' or a cf-* element exists.","commonSituations":"Scraping from a datacenter/VPN IP flagged by Cloudflare; headless or automation-flagged browser profile; too many rapid requests from the same session; cookies cleared so no clearance token exists.","solutions":["Open https://www.indeed.com in the connected browser and manually solve the challenge, then retry","Use a normal (non-headless) browser session with a real user profile","Switch network: disable VPN/proxy or use a residential IP","Slow down request rate / add delays between Indeed requests","Clear and re-establish a Cloudflare clearance by browsing Indeed normally once before scraping"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const title = await page.title();\nif (title.includes('Just a moment') || (await page.$('[id^=\"cf-\"]'))) {\n  // solve the challenge manually in the connected browser before running the command\n}","typeGuard":null,"tryCatchPattern":"try {\n  const job = await indeed.job(jk);\n} catch (e) {\n  if (e.message.includes('Cloudflare challenge')) {\n    // prompt user to clear the challenge in the connected browser, wait, then retry\n  }\n  throw e;\n}","preventionTips":["Use a non-headless browser with a real profile and history","Avoid VPN/datacenter IPs for Indeed scraping","Space out requests; don't burst-scrape","Browse Indeed normally first to earn Cloudflare clearance cookies"],"tags":["cloudflare","bot-detection","scraping","indeed"],"backgroundTag":"cloudflare-challenge-blocked","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}