{"record":{"id":"8475fc9c8cbd26bd","repo":"santifer/career-ops","slug":"liveness-requires-playwright-with-chromium-run","errorCode":null,"errorMessage":"--liveness requires Playwright with Chromium (run \"npx playwright install chromium\"): ${err.message}","messagePattern":"--liveness requires Playwright with Chromium \\(run \"npx playwright install chromium\"\\): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scan-ats-full.mjs","lineNumber":675,"sourceCode":"        // Lowest not-yet-finished index: everything below it is complete, so\n        // a resumed run can restart exactly here without skipping work.\n        const resumeAt = inFlight.size ? Math.min(...inFlight) : next;\n        if (onItemDone) onItemDone({ done, resumeAt });\n      }\n    }\n  }\n  await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));\n}\n\n// ── Liveness verification (reuses liveness-browser.mjs) ────────────\n\nasync function filterLive(offers) {\n  let chromium, checkUrlLiveness, newLivenessPage;\n  try {\n    ({ chromium } = await import('playwright'));\n    ({ checkUrlLiveness, newLivenessPage } = await import('./liveness-browser.mjs'));\n  } catch (err) {\n    throw new Error(\n      `--liveness requires Playwright with Chromium (run \"npx playwright install chromium\"): ${err.message}`,\n      { cause: err },\n    );\n  }\n  console.error(`\\nVerifying liveness of ${offers.length} match(es) with Playwright (sequential)...`);\n  const browser = await chromium.launch({ headless: true });\n  const live = [];\n  try {\n    const page = await newLivenessPage(browser);\n    // Sequential — project rule: never Playwright in parallel\n    for (const offer of offers) {\n      const { result, reason } = await checkUrlLiveness(page, offer.url);\n      const icon = result === 'active' ? '✅' : result === 'expired' ? '❌' : '⚠️';\n      console.error(`  ${icon} ${result.padEnd(9)} ${offer.company} | ${offer.title}${result === 'expired' ? ` (${reason})` : ''}`);\n      if (result !== 'expired') live.push(offer); // keep 'uncertain' — transient errors retry next scan\n    }\n  } finally {\n    await browser.close();","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/santifer/career-ops/blob/e7abd431fce9348a95261acac9e0c14779c35df8/scan-ats-full.mjs#L657-L693","documentation":"filterLive verifies matched offers with a headless Chromium browser. The library throws this when the dynamic import of 'playwright' or './liveness-browser.mjs' fails, i.e. Playwright is not installed or its Chromium browser binary is missing. The thrown error chains the original import failure as `cause`.","triggerScenarios":"Running scan-ats-full.mjs with the --liveness flag in an environment where playwright is not an installed npm dependency, or playwright is installed but `npx playwright install chromium` was never run (browser binaries absent), or liveness-browser.mjs is missing from the repo.","commonSituations":"Fresh clone / CI container without post-install browser download; running with a stripped node_modules; using a Node version incompatible with the installed Playwright build; global vs local install mismatch.","solutions":["Run `npx playwright install chromium` to download the browser binary","Ensure playwright is a project dependency: `npm install playwright`","If liveness-browser.mjs is missing, re-clone or restore the repo files","Re-run the scan without --liveness if browser verification is not needed"],"exampleFix":"// shell, before\nnode scan-ats-full.mjs --liveness   # Error: requires Playwright with Chromium\n// after\nnpm install playwright\nnpx playwright install chromium\nnode scan-ats-full.mjs --liveness","handlingStrategy":"fallback","validationCode":"// run before using --liveness\nlet playwrightOk = true;\ntry { await import('playwright'); } catch { playwrightOk = false; }\nif (!playwrightOk) console.warn('--liveness unavailable: run npx playwright install chromium');","typeGuard":null,"tryCatchPattern":"try {\n  await runWithLiveness(offers);\n} catch (err) {\n  if (err.message.includes('--liveness requires Playwright')) {\n    console.warn('Skipping liveness check:', err.cause?.message ?? err.message);\n    return offers; // degrade gracefully\n  }\n  throw err;\n}","preventionTips":["Run `npx playwright install chromium` after every fresh clone or npm ci in CI","Add a doctor/setup check that probes `import('playwright')` before enabling browser features","Pin playwright as a regular dependency, not an optional one, when liveness is required"],"tags":["playwright","missing-dependency","browser","cli"],"backgroundTag":"missing-optional-dependency","analyzedSha":"e7abd431fce9348a95261acac9e0c14779c35df8","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}