santifer/career-ops · warning
⚠️ config/profile.yml cv.sections names
Error message
⚠️ config/profile.yml cv.sections names ${names}, which matched no section in this CV. The CV also renders ${unrecognized.size} section title(s) the section-order alias table doesn't recognize (${titles}) — if one of those is the section you meant, its title needs an entry in SECTION_ALIASES in generate-pdf.mjs. Otherwise the name has no effect and can be dropped. What it means
After applying cv.sections, generate-pdf.mjs reports unresolved names — but only when the CV also renders section titles the SECTION_ALIASES table does not recognize, because that combination suggests the user named a real section by a title the alias table lacks. The warning tells the user to add a SECTION_ALIASES entry or drop the name.
Solutions
- Check the rendered titles listed in the warning; if one is the section you meant, add a mapping to SECTION_ALIASES in generate-pdf.mjs
- If the name is simply not in this CV (optional section with no entries), remove it from cv.sections
- Regenerate the PDF and confirm the order now applies
Example fix
// before: generate-pdf.mjs
const SECTION_ALIASES = { experience: ['Work Experience'], skills: ['Skills'] };
// after: alias the novel heading
const SECTION_ALIASES = { experience: ['Work Experience'], skills: ['Skills'], opensource: ['Open Source'] }; Defensive patterns
Strategy: validation
Validate before calling
// ensure every cv.sections name resolves and every rendered title has an alias
const renderedTitles = extractRenderedSectionTitles(html);
const unmapped = renderedTitles.filter(t => !aliasTableHasTitle(t));
const unresolved = (profile.cv?.sections ?? []).filter(n => !findSectionBlock(html, n));
if (unresolved.length && unmapped.length) console.warn('add SECTION_ALIASES entries for:', unmapped); Type guard
const isAliasMapped = (title, aliases) => Object.values(aliases).some(list => list.includes(title));
Prevention
- When renaming a section heading in the template, update SECTION_ALIASES in the same change
- Keep cv.sections limited to sections that actually exist in the current CV
- Run PDF generation once after template changes and read all ⚠️ output before shipping
When it happens
Trigger: reorderCvSections finished with entries in `unresolved` (recognized names that matched no section block) AND the `unrecognized` set of rendered-but-unknown section titles is non-empty. reportUnresolved() at generate-pdf.mjs:976 emits this combined warning; it stays silent if either set is empty.
Common situations: A custom CV template uses a novel section heading (e.g. 'Open Source') that SECTION_ALIASES does not map, while the user lists the intended section key in cv.sections; renamed headings after a template update.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- ⚠️ config/profile.yml cv.sections lists only
- ⚠️ config/profile.yml cv.sections lists
- ⚠️ config/profile.yml cv.sections lists
- ⚠️ No config/cv-facts.json — forbidden/advisory phrase…
- ⚠️ config/profile.yml cv.sections lists
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/9664fb1370e9f4c2.
Report an issue: GitHub.
Appendix: source
Thrown at generate-pdf.mjs:982
}
}
// It is worth one when the CV also renders titles the alias table can't name,
// because then "not in this CV" may be a misreading: the section could be
// sitting right there under a heading nothing could identify.
//
// Whether that is what happened is not knowable here — an unresolved name may
// equally be an optional section with no entries. So the report states only
// what is checkable (this name matched nothing; these titles are unidentified)
// and leaves the conclusion to the reader. Deliberately not conditioned on
// whether the document changed: a name that did nothing did nothing, whether
// or not its neighbours moved, and treating "output identical" as the failure
// signal misreads an order that was already satisfied.
const reportUnresolved = () => {
if (unresolved.length === 0 || unrecognized.size === 0) return;
const names = unresolved.map(name => `"${displayTitle(name)}"`).join(', ');
const titles = [...unrecognized.values()].map(title => `"${title}"`).join(', ');
console.warn(`⚠️ config/profile.yml cv.sections names ${names}, which matched no section in this CV. The CV also renders ${unrecognized.size} section title(s) the section-order alias table doesn't recognize (${titles}) — if one of those is the section you meant, its title needs an entry in SECTION_ALIASES in generate-pdf.mjs. Otherwise the name has no effect and can be dropped.`);
};
if (chosen.length < 2) {
reportUnresolved();
return html;
}
// The slots are the named sections' own positions, in document order; the
// sections fill them in the configured order. No separate sibling check is
// needed: every accepted block is balanced, so they all sit at the same
// nesting level by construction.
const slots = [...chosen].sort((a, b) => a.start - b.start);
let out = '';
let cursor = 0;
for (let i = 0; i < slots.length; i++) {
out += html.slice(cursor, slots[i].start);
out += html.slice(chosen[i].start, chosen[i].end);
cursor = slots[i].end;View on GitHub (pinned to aac998c7ed)