santifer/career-ops · warning
⚠️ CV fact check warning
Error message
⚠️ CV fact check warning: ${basename(inputPath)} What it means
generate-pdf.mjs runs a fact-check pass over the generated CV (metrics and facts against config/cv-facts.json, plus forbidden/advisory phrase lists). When the fact-check verdict is 'warn', it prints this warning naming the input file, followed by one line per advisory phrase found. It is a non-fatal console.warn: the PDF still renders.
Solutions
- Read the ' - advisory phrase:' lines printed immediately after and rewrite those phrases in cv.md or the generated CV
- Re-run the PDF generation and confirm the verdict changes to '✅ Fact check passed'
- If a flagged phrase is actually fine, add it to an allowlist in config/cv-facts.json
- If config/cv-facts.json is missing, create it so forbidden/advisory checks actually run (the warning above this one indicates they were skipped)
Example fix
// before draft: "I was involved in migrating the pipeline" // after draft: "Migrated the ingestion pipeline, cutting batch time 40%"
Defensive patterns
Strategy: validation
Validate before calling
// run the fact-check standalone before rendering
const fc = await factCheckCV(cvText, config);
if (fc.verdict === 'warn') fc.warnings.forEach(w => console.log('advisory:', w)); Prevention
- Keep config/cv-facts.json present so phrase checks actually run
- Lint cv.md against the advisory phrase list before each PDF build
- Treat the '✅ Fact check passed' line as a release gate for CVs
When it happens
Trigger: Running the CV/PDF mode when factCheckCV() returns verdict 'warn' — i.e. the CV text contains phrases on the advisory list (hedged or risky wording) but nothing on the forbidden list.
Common situations: CV drafts containing advisory phrasing like 'helped with', 'involved in', or unquantified claims the phrase lists flag; authors reviewing generated PDFs before sending them out.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- - advisory phrase
- ⚠️ No config/cv-facts.json — forbidden/advisory phrase…
- ⚠️ config/profile.yml cv.sections lists only
- ⚠️ config/profile.yml cv.sections lists
- ⚠️ config/profile.yml cv.sections lists
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/fb7c689a835a051b.
Report an issue: GitHub.
Appendix: source
Thrown at generate-pdf.mjs:1363
// normalized HTML, which is the document that actually prints.
if (!skipFactCheck && cvMarkdown) {
// Imported lazily, INSIDE the guard. A static import is resolved at module
// load whether or not this branch runs, and the page-budget/batch suites copy
// generate-pdf.mjs alone into a temp workspace — a static import of a sibling
// that isn't copied made every one of those suites die with
// ERR_MODULE_NOT_FOUND before reaching the behaviour under test. Those
// fixtures also ship no cv.md, so this branch is never entered there. If the
// module is genuinely missing in a real workspace this throws and the render
// fails, which is the correct direction to fail for a fact gate.
const { assertFacts } = await import('./verify-cv-facts.mjs');
const factCheck = assertFacts(html, { label: basename(inputPath) });
// Ahead of the verdict, because it qualifies it: with no config the phrase
// lists are empty, so a "passed" below covers metrics and facts only.
if (factCheck.configMissing) {
console.warn('⚠️ No config/cv-facts.json — forbidden/advisory phrase checks did not run.');
}
if (factCheck.verdict === 'warn') {
console.warn(`⚠️ CV fact check warning: ${basename(inputPath)}`);
for (const phrase of factCheck.warnings) console.warn(` - advisory phrase: ${phrase}`);
} else {
console.log('✅ Fact check passed');
}
}
return renderHtmlToPdf(html, outputPath, {
format,
baseDir: dirname(inputPath),
reportNum,
inputPath,
maxPages,
strictPages,
styleTokens: readStyleTokens(resolve(workspaceRoot, 'config', 'profile.yml')),
});
}
/**View on GitHub (pinned to aac998c7ed)