affaan-m/ECC · error · Error

DOCX required: pandoc unavailable; use --markdown-only for…

Error message

DOCX required: pandoc unavailable; use --markdown-only for an explicit Markdown-only draft

What it means

After writing the Markdown draft, build() converts it to DOCX with pandoc. If DOCX conversion is requested (the default) and pandoc is not available on PATH (or options.pandoc resolves to false) without --markdown-only, it throws this error directing the user to the explicit markdown-only escape hatch. The library treats DOCX as required unless the user explicitly opts out.

Solutions

  1. Install pandoc (e.g. brew install pandoc, apt-get install pandoc, choco install pandoc) and confirm with `pandoc --version`.
  2. If DOCX genuinely isn't needed, pass --markdown-only on the CLI (or { markdownOnly: true } programmatically) to explicitly skip conversion.
  3. Verify pandoc is on PATH for the environment running the script (CI containers may differ from your shell).
  4. Prefer an explicit install over disabling conversion — the error is deliberately worded to force a conscious choice.

Example fix

// before
node build-agreement.js --spec spec.json --out out   # pandoc missing -> throws
// after
brew install pandoc           # or: apt-get install -y pandoc
node build-agreement.js --spec spec.json --out out
# or, if DOCX not needed:
node build-agreement.js --spec spec.json --out out --markdown-only
Defensive patterns

Strategy: fallback

Validate before calling

const { spawnSync } = require('child_process');
const hasPandoc = spawnSync('pandoc', ['--version']).status === 0;
if (!hasPandoc && requireDocx) throw new Error('pandoc must be installed');

Type guard

null

Try / catch

try {
  build(templatePath, specPath, outDir);
} catch (e) {
  if (e.message.includes('pandoc unavailable')) {
    console.error('Install pandoc, or rerun with --markdown-only if DOCX is optional');
  } else throw e;
}

Prevention

When it happens

Trigger: Running the script without --markdown-only on a machine where pandoc is not installed or not on PATH; running in a minimal container/CI image lacking pandoc; options.pandoc=false passed programmatically without markdownOnly:true.

Common situations: Fresh dev machine or Docker image without pandoc; Windows CI runners where pandoc isn't preinstalled; calling build() from another Node script and forgetting to set options.markdownOnly.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/0cfcf25b78252e5a. Report an issue: GitHub.

Appendix: source

Thrown at skills/master-agreement-generator/scripts/build-agreement.js:179

function build(templatePath, specPath, outDir, options = {}) {
  const template = fs.readFileSync(templatePath, 'utf8');
  const spec = JSON.parse(fs.readFileSync(specPath, 'utf8'));
  const markdown = render(template, spec, options.now);
  const { root, mdPath, docxPath } = outputPaths(outDir, spec.file);
  fs.mkdirSync(root, { recursive: true });
  fs.writeFileSync(mdPath, markdown, 'utf8');

  // Generated DOCX is replaceable output. Never leave a stale or partial copy
  // beside a newly built Markdown draft, including explicit Markdown-only builds.
  fs.rmSync(docxPath, { force: true });
  const result = { markdown: mdPath, docx: null, docxSkipped: false, documentStatus: 'draft' };
  if (options.markdownOnly === true) {
    result.docxSkipped = true;
    return result;
  }
  const canConvert = options.pandoc === undefined ? pandocAvailable() : options.pandoc;
  if (!canConvert) {
    throw new Error('DOCX required: pandoc unavailable; use --markdown-only for an explicit Markdown-only draft');
  }
  try {
    const converted = spawnSync('pandoc', [mdPath, '-o', docxPath], CONVERTER_OPTIONS);
    if (converted.error || converted.status !== 0) {
      throw new Error('pandoc conversion failed; DOCX unavailable');
    }
    const artifact = fs.lstatSync(docxPath);
    if (!artifact.isFile() || artifact.size === 0) {
      throw new Error('pandoc did not produce a nonempty regular DOCX artifact');
    }
  } catch (error) {
    fs.rmSync(docxPath, { force: true });
    if (error.code === 'ENOENT') throw new Error('pandoc did not produce a DOCX artifact');
    throw error;
  }
  result.docx = docxPath;
  return result;
}

View on GitHub (pinned to 8321021c54)