santifer/career-ops · error · Error
--liveness requires Playwright with Chromium (run "npx…
Error message
--liveness requires Playwright with Chromium (run "npx playwright install chromium"): ${err.message} What it means
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`.
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
Example fix
// shell, before node scan-ats-full.mjs --liveness # Error: requires Playwright with Chromium // after npm install playwright npx playwright install chromium node scan-ats-full.mjs --liveness
Defensive patterns
Strategy: fallback
Validate before calling
// run before using --liveness
let playwrightOk = true;
try { await import('playwright'); } catch { playwrightOk = false; }
if (!playwrightOk) console.warn('--liveness unavailable: run npx playwright install chromium'); Try / catch
try {
await runWithLiveness(offers);
} catch (err) {
if (err.message.includes('--liveness requires Playwright')) {
console.warn('Skipping liveness check:', err.cause?.message ?? err.message);
return offers; // degrade gracefully
}
throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- --verify requires Playwright with Chromium (run "npx…
- archive render skipped — no Playwright browser in env
- ⚠️ Browser cleanup failed
- [fetch] Playwright error
- [fetch] Playwright unavailable — falling back to plain…
AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16).
Data as JSON: /api/errors/8475fc9c8cbd26bd.
Report an issue: GitHub.
Appendix: source
Thrown at scan-ats-full.mjs:675
// Lowest not-yet-finished index: everything below it is complete, so
// a resumed run can restart exactly here without skipping work.
const resumeAt = inFlight.size ? Math.min(...inFlight) : next;
if (onItemDone) onItemDone({ done, resumeAt });
}
}
}
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));
}
// ── Liveness verification (reuses liveness-browser.mjs) ────────────
async function filterLive(offers) {
let chromium, checkUrlLiveness, newLivenessPage;
try {
({ chromium } = await import('playwright'));
({ checkUrlLiveness, newLivenessPage } = await import('./liveness-browser.mjs'));
} catch (err) {
throw new Error(
`--liveness requires Playwright with Chromium (run "npx playwright install chromium"): ${err.message}`,
{ cause: err },
);
}
console.error(`\nVerifying liveness of ${offers.length} match(es) with Playwright (sequential)...`);
const browser = await chromium.launch({ headless: true });
const live = [];
try {
const page = await newLivenessPage(browser);
// Sequential — project rule: never Playwright in parallel
for (const offer of offers) {
const { result, reason } = await checkUrlLiveness(page, offer.url);
const icon = result === 'active' ? '✅' : result === 'expired' ? '❌' : '⚠️';
console.error(` ${icon} ${result.padEnd(9)} ${offer.company} | ${offer.title}${result === 'expired' ? ` (${reason})` : ''}`);
if (result !== 'expired') live.push(offer); // keep 'uncertain' — transient errors retry next scan
}
} finally {
await browser.close();View on GitHub (pinned to e7abd431fc)