santifer/career-ops · error · Error

Unresolved placeholders: ${[...new Set(unresolved)].join(',

Error message

Unresolved placeholders: ${[...new Set(unresolved)].join(', ')}

What it means

Error "Unresolved placeholders: ${[...new Set(unresolved)].join(', ')}" thrown in santifer/career-ops.

Source

Thrown at build-cv-html.mjs:635

  const { substitutions, candidate } = renderReport(payload, partials);

  // The contact row and photo carry conditional markup (dropped separators /
  // no <img>), so they are rebuilt as whole blocks before placeholder fill.
  let html = template.replace(CONTACT_ROW_RE, () => buildContactRow(candidate));
  html = html.replace(/\{\{PHOTO\}\}/g, () => buildPhoto(candidate, candidate.name));

  // Drop the optional sections (projects, education) that have no entries, so
  // an absent one leaves no bare header behind. See cv-sections-core.mjs.
  html = stripEmptySections(html, payload, 'html');

  for (const [key, value] of Object.entries(substitutions)) {
    html = html.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), () => value);
  }

  const unresolved = html.match(PLACEHOLDER_RE);
  if (unresolved) {
    throw new Error(`Unresolved placeholders: ${[...new Set(unresolved)].join(', ')}`);
  }
  return html;
}

function countBullets(payload) {
  const ex = Array.isArray(payload.experience)
    ? payload.experience.flatMap(e => (Array.isArray(e?.bullets) ? e.bullets : []))
    : [];
  return ex.length;
}

async function writeAndReport(html, absOutput, payload, extra = {}) {
  const outDir = dirname(absOutput);
  if (!existsSync(outDir)) await mkdir(outDir, { recursive: true });
  await writeFile(absOutput, html, 'utf-8');

  const fileInfo = await stat(absOutput);
  const report = {

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Add values for the listed placeholders in cv.md or the profile config, then rebuild.
  2. Or remove the placeholders from the CV template if they are not used.

Example fix

# fill {{email}} and {{location}} in config/profile.yml, then re-run build-cv-html.mjs

When it happens

Trigger: Thrown at build-cv-html.mjs:635 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/d63e5c481b244e61. Report an issue: GitHub.