{"record":{"id":"0dfc30d02d2a8b5c","repo":"santifer/career-ops","slug":"config-profile-yml-cv-sections-lists-shown-0dfc30","errorCode":null,"errorMessage":"⚠️  config/profile.yml cv.sections lists \"${shown}\", but this CV's markup does not enclose that section on its own — leaving it in place, because moving it would leave tags unbalanced.","messagePattern":"⚠️  config/profile\\.yml cv\\.sections lists \"(.+?)\", but this CV's markup does not enclose that section on its own — leaving it in place, because moving it would leave tags unbalanced\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"generate-pdf.mjs","lineNumber":958,"sourceCode":"    if (seen.has(name)) {\n      console.warn(`⚠️  config/profile.yml cv.sections lists \"${shown}\" more than once — keeping its first position.`);\n      continue;\n    }\n    seen.add(name);\n    if (!CV_SECTION_KEYS.includes(name)) {\n      console.warn(`⚠️  config/profile.yml cv.sections lists \"${shown}\", which is not a CV section — ignoring it. Recognized: ${CV_SECTION_KEYS.join(', ')}.`);\n      continue;\n    }\n    const block = byKey.get(name);\n    if (block) {\n      chosen.push(block);\n    } else if (ambiguous.has(name)) {\n      // Present, but its markup doesn't stand on its own — it opens or closes\n      // elements outside itself, so moving it would leave tags unbalanced.\n      // Reported rather than skipped quietly: the section stays where the\n      // template put it, and the user would otherwise see a setting that\n      // silently does nothing.\n      console.warn(`⚠️  config/profile.yml cv.sections lists \"${shown}\", but this CV's markup does not enclose that section on its own — leaving it in place, because moving it would leave tags unbalanced.`);\n    } else {\n      // Recognized and unambiguous but with no block. Ordinarily that just means\n      // the section isn't in this CV (an optional one with no entries is\n      // stripped before the PDF step), which is not worth a warning on its own.\n      unresolved.push(name);\n    }\n  }\n\n  // It is worth one when the CV also renders titles the alias table can't name,\n  // because then \"not in this CV\" may be a misreading: the section could be\n  // sitting right there under a heading nothing could identify.\n  //\n  // Whether that is what happened is not knowable here — an unresolved name may\n  // equally be an optional section with no entries. So the report states only\n  // what is checkable (this name matched nothing; these titles are unidentified)\n  // and leaves the conclusion to the reader. Deliberately not conditioned on\n  // whether the document changed: a name that did nothing did nothing, whether\n  // or not its neighbours moved, and treating \"output identical\" as the failure","sourceCodeStart":940,"sourceCodeEnd":976,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/generate-pdf.mjs#L940-L976","documentation":"When reordering, generate-pdf.mjs extracts each named section as a self-contained HTML block. If a named section is present but its markup does not stand alone (it opens or closes elements outside its own span), moving it would leave unbalanced tags — so the section is left in place and this warning reports the no-op rather than silently ignoring the setting.","triggerScenarios":"A cv.sections name resolves to a section that IS found in the CV but whose extracted HTML block is marked ambiguous (present in the `ambiguous` set) — the template wraps or splits its tags across sibling sections. Fired at generate-pdf.mjs:957 during reorderCvSections.","commonSituations":"A custom or hand-edited CV template (templates/cv-template.html) structures a section with elements spanning boundaries; a section heading sits outside its content wrapper so the block cannot be cleanly cut.","solutions":["Fix the template so each section's markup is fully enclosed in its own block (open and close tags inside the section)","If the template cannot change, remove that name from cv.sections and accept the template's default position","Re-run PDF generation after fixing the markup and confirm the order applies"],"exampleFix":"<!-- before: unbalanced markup -->\n<div class=\"sections\">\n  <h2>Skills</h2>\n  <ul>...</ul>\n<!-- experience opens inside skills wrapper -->\n  <h2>Experience</h2>\n</div>\n<!-- after: each section self-contained -->\n<section id=\"skills\"><h2>Skills</h2><ul>...</ul></section>\n<section id=\"experience\"><h2>Experience</h2>...</section>","handlingStrategy":"validation","validationCode":"// check that each named section's markup is self-contained before relying on reordering\nfor (const name of profile.cv?.sections ?? []) {\n  if (!sectionBlockIsStandalone(html, name)) console.warn(`${name} markup is not self-contained; reorder will skip it`);\n}","typeGuard":"const canReorder = (name, ambiguousSet) => !ambiguousSet.has(name);","tryCatchPattern":null,"preventionTips":["Keep the CV template's sections fully enclosed: each section opens and closes its own tags","Test reordering after any template edit","Prefer <section> wrappers per section in custom templates"],"tags":["cv","pdf","html","template","ordering"],"backgroundTag":"unsupported-operation","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"}