{"record":{"id":"a209c415216c5853","repo":"santifer/career-ops","slug":"enoent","errorCode":"ENOENT","errorMessage":"⚠️  Font file not found, keeping original reference: fonts/${name}","messagePattern":"⚠️  Font file not found, keeping original reference: fonts/(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"generate-pdf.mjs","lineNumber":1606,"sourceCode":"    const fontPath = resolve(fontsDir, name);\n    const rel = relative(fontsDir, fontPath);\n    if (rel.startsWith('..') || isAbsolute(rel)) {\n      console.warn(`⚠️  Font reference escapes fonts/, keeping original reference: ${name}`);\n      continue;\n    }\n    if (_fontDataUrlCache.has(fontPath)) {\n      dataUrls.set(name, _fontDataUrlCache.get(fontPath));\n      continue;\n    }\n    try {\n      const buf = await readFile(fontPath);\n      const ext = name.slice(name.lastIndexOf('.') + 1).toLowerCase();\n      const dataUrl = `url('data:${MIME[ext] || 'application/octet-stream'};base64,${buf.toString('base64')}')`;\n      _fontDataUrlCache.set(fontPath, dataUrl);\n      dataUrls.set(name, dataUrl);\n    } catch (err) {\n      if (err?.code !== 'ENOENT') throw err;\n      console.warn(`⚠️  Font file not found, keeping original reference: fonts/${name}`);\n    }\n  }\n  return html.replace(FONT_REF, (match, _quote, name) => dataUrls.get(name) || match);\n}\n\n/**\n * Render an HTML string to a PDF file via headless Chromium.\n *\n * Writes the HTML to a temporary file in the baseDir and loads it via\n * page.goto() to give the page a file:// origin. This allows relative\n * resources (images, fonts) to load — setContent() runs from about:blank\n * and Chromium blocks file:// subresource loads from non-file origins.\n *\n * Local url('./fonts/...') references are inlined as data: URLs first so\n * fonts also survive the ATS normalization pass (which may strip font refs).\n *\n * @param {string} html - Full HTML document to render.\n * @param {string} outputPath - Absolute path to write the PDF to.","sourceCodeStart":1588,"sourceCodeEnd":1624,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/generate-pdf.mjs#L1588-L1624","documentation":"generate-pdf.mjs inlines font files referenced by an HTML CV as base64 data URLs before rendering with Playwright. When a font file referenced as fonts/<name> does not exist on disk, the read throws ENOENT; the code deliberately downgrades it to a warning and keeps the original CSS reference, so the PDF renders with a fallback font (or a broken reference) instead of the intended typeface.","triggerScenarios":"FONT_REF replacement loop calls fs read on a fonts/<name> path that does not exist — cv.md/template references a font family (e.g. fonts/Inter-Regular.woff2) that was never placed in the fonts/ directory, the font file was renamed or deleted, or the script runs from a working directory where fonts/ is not present.","commonSituations":"Using a custom cv-template.html that names a specific font but only vendoring part of the family (missing weights); cloning the repo without the fonts directory (gitignored binaries); running generate-pdf.mjs from a different cwd than the repo root so relative paths resolve wrong.","solutions":["Place the missing font file at the referenced path: find the <name> from the warning and copy that exact filename into fonts/ next to generate-pdf.mjs","Run the script from the repo root so the relative fonts/ path resolves","Update the HTML/CSS template to reference an installed system font (e.g. 'Arial', sans-serif) instead of fonts/<name> if vendoring is not desired"],"exampleFix":"// before (fonts dir incomplete)\ncv-template.html: @font-face { src: url('fonts/Inter-Bold.woff2'); } // file absent -> ENOENT\n// after\ncp ~/Downloads/Inter-Bold.woff2 fonts/Inter-Bold.woff2","handlingStrategy":"fallback","validationCode":"import { accessSync, constants } from 'node:fs';\nfunction fontFileExists(fontPath) {\n  try { accessSync(fontPath, constants.R_OK); return true; } catch { return false; }\n}\nif (!fontFileExists(`fonts/${name}`)) console.warn(`Font missing: fonts/${name}`);","typeGuard":null,"tryCatchPattern":"try {\n  const buf = await fs.readFile(fontPath);\n  // inline as data URL\n} catch (err) {\n  if (err?.code === 'ENOENT') return keepOriginalReference();\n  throw err;\n}","preventionTips":["Vendor all referenced font files into fonts/ and commit or install them","Run PDF generation from the repo root","Add a startup check that every @font-face URL in the template resolves to a file","Keep font names in the template in sync with the fonts directory listing"],"tags":["fonts","playwright","pdf","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}