santifer/career-ops · warning

Cannot import generate-pdf.mjs

Error message

Cannot import generate-pdf.mjs (${e.code || e.message}) — skipping behavioral section-order tests

What it means

generate-pdf.mjs imports Playwright at module scope, so dynamic import of it fails in environments without Playwright installed. test-all.mjs catches that import error and warns that the behavioral section-order tests are skipped rather than letting the suite crash.

Solutions

  1. Run `npm install` (or `npm i playwright && npx playwright install chromium`) in the repo root so the module imports.
  2. Read e.code/e.message in the warning: ERR_MODULE_NOT_FOUND → install deps; syntax errors → fix generate-pdf.mjs.
  3. If you only need the pure functions (sectionKey, validateCvSectionOrder), consider importing from a module that does not pull Playwright at top level.
  4. Accept the skip if CV rendering is irrelevant to your change — it is an intentional degradation.

Example fix

// before (generate-pdf.mjs)
import { chromium } from 'playwright';
// after (lazy, so importers without playwright still work)
let chromium;
export async function getChromium() { ({ chromium } = await import('playwright')); return chromium; }
Defensive patterns

Strategy: try-catch

Validate before calling

let importable = true; try { await import(pathToFileURL('generate-pdf.mjs').href); } catch { importable = false; } if (!importable) console.warn('run npm install to enable pdf tests');

Type guard

const pdfImportable = (m) => m !== null && typeof m.validateCvSectionOrder === 'function';

Try / catch

try { pdfModule = await import(pathToFileURL(join(ROOT, 'generate-pdf.mjs')).href); } catch (e) { warn(`Cannot import generate-pdf.mjs (${e.code || e.message})`); }

Prevention

When it happens

Trigger: `await import(pathToFileURL(join(ROOT, 'generate-pdf.mjs')).href)` rejects — typically with ERR_MODULE_NOT_FOUND because the playwright package is missing, or a syntax/compat error (non-zero e.code, message in e.message) in generate-pdf.mjs itself.

Common situations: Fresh clones without `npm install`, CI jobs that skip browser dependencies, Node version mismatch making the module fail to parse, or a broken generate-pdf.mjs after an edit.

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


AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-16). Data as JSON: /api/errors/877d012a7cf93736. Report an issue: GitHub.

Appendix: source

Thrown at test-all.mjs:2730

// Same gap, same two shipped Chinese markets (#3658): modes/zh-TW and modes/zh
// rendered titles the alias table could not name, so the guard was disabled AND
// cv.sections — the documented way to correct an order — silently did nothing.
// Both scripts are required: a CV written in either renders through this table.
for (const header of ['專業摘要', '工作經歷', '學歷', '證照', '技能', '专业摘要', '工作经历', '学历', '证书', '项目']) {
  if (generatePdfScript.includes(`['${header}',`)) {
    pass(`SECTION_ALIASES maps Chinese header: ${header}`);
  } else {
    fail(`SECTION_ALIASES missing Chinese header: ${header}`);
  }
}

// generate-pdf.mjs imports playwright at module scope; degrade to a warning
// rather than crashing the suite where it is not installed.
let pdfModule = null;
try {
  pdfModule = await import(pathToFileURL(join(ROOT, 'generate-pdf.mjs')).href);
} catch (e) {
  warn(`Cannot import generate-pdf.mjs (${e.code || e.message}) — skipping behavioral section-order tests`);
}

if (pdfModule) {
  const { sectionKey, validateCvSectionOrder } = pdfModule;

  // Canonical keys are language-independent; only the spelling differs.
  const keyCases = [
    ['Podsumowanie zawodowe', 'summary'],
    ['Kompetencje kluczowe', 'competencies'],
    ['Kluczowe kompetencje', 'competencies'], // word-order variant
    ['Doświadczenie zawodowe', 'experience'],
    ['Przebieg kariery', 'experience'],
    ['Wykształcenie', 'education'],
    ['Certyfikaty', 'certifications'],
    ['Umiejętności', 'skills'],
    ['Wyksztalcenie', 'education'],  // diacritics stripped
    ['Umiejetnosci', 'skills'],      // diacritics stripped
    ['Work Experience', 'experience'], // English must be unchanged

View on GitHub (pinned to e7abd431fc)