affaan-m/ECC · error · Error

pandoc conversion failed; DOCX unavailable

Error message

pandoc conversion failed; DOCX unavailable

What it means

When pandoc is present, build() spawns `pandoc <mdPath> -o <docxPath>` and throws this error if the spawn itself errored (converted.error) or pandoc exited non-zero. Unlike error 727 (pandoc not found at all), this means conversion was attempted and failed, so the DOCX output is unavailable and any partial docx is cleaned up.

Solutions

  1. Run `pandoc <mdPath> -o <docxPath>` manually on the generated .md to see pandoc's actual stderr.
  2. Upgrade or reinstall pandoc to a current version (pandoc --version).
  3. Simplify/inspect the generated Markdown near any nonstandard content (wide tables, raw HTML) that pandoc may reject.
  4. If the spawn error was EACCES/ENOENT rather than a pandoc failure, fix the binary's permissions or PATH.

Example fix

// before
$ pandoc out/NDA\ MASTER.md -o out/NDA\ MASTER.docx
pandoc: unrecognized option `--xyz' (exit 1)
// after
$ pandoc --version   # check/upgrade version
$ brew upgrade pandoc  # or apt-get install --only-upgrade pandoc
$ node build-agreement.js --spec spec.json --out out  # retry
Defensive patterns

Strategy: retry

Validate before calling

const { spawnSync } = require('child_process');
const probe = spawnSync('pandoc', ['--version']);
if (probe.error || probe.status !== 0) throw new Error('pandoc broken or not executable');

Type guard

null

Try / catch

try {
  build(templatePath, specPath, outDir);
} catch (e) {
  if (e.message === 'pandoc conversion failed; DOCX unavailable') {
    console.error('Run pandoc manually on the .md to see the real error; check pandoc version');
  } else throw e;
}

Prevention

When it happens

Trigger: Pandoc installed but failing on the generated Markdown (unsupported construct, huge tables); a broken pandoc install or incompatible version; converted.error from spawn failure (e.g. EACCES on the pandoc binary).

Common situations: Very old pandoc versions choking on newer Markdown features; restricted CI environments where the pandoc binary can't execute; intermediary pandoc filters failing and returning a non-zero exit code.

Related errors


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

Appendix: source

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

  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;
}

function main(argv) {
  const [templatePath, specPath, outDir, ...flags] = argv;
  if (!templatePath || !specPath || !outDir ||
      flags.some(flag => !['--require-docx', '--markdown-only'].includes(flag)) ||

View on GitHub (pinned to 8321021c54)