affaan-m/ECC · error · Error

Failed to read ${normalizePath(path.relative(ROOT, outputPat

Error message

Failed to read ${normalizePath(path.relative(ROOT, outputPath))}: ${error.message}

What it means

`checkRegistry` (invoked by `generate-command-registry.js --check`) reads `docs/COMMAND-REGISTRY.json` from disk via `fs.readFileSync` and compares it to a freshly-generated registry. If the read itself fails (file does not exist, permission denied, path is a directory), the throw `Failed to read docs/COMMAND-REGISTRY.json: <error.message>` fires. This is a missing/unreadable-artifact error, not a staleness error.

Source

Thrown at scripts/ci/generate-command-registry.js:223

}

function formatRegistry(registry) {
  return `${JSON.stringify(registry, null, 2)}\n`;
}

function writeRegistry(registry, outputPath = DEFAULT_OUTPUT_PATH) {
  fs.mkdirSync(path.dirname(outputPath), { recursive: true });
  fs.writeFileSync(outputPath, formatRegistry(registry), 'utf8');
}

function checkRegistry(registry, outputPath = DEFAULT_OUTPUT_PATH) {
  const expected = formatRegistry(registry);
  let current;

  try {
    current = fs.readFileSync(outputPath, 'utf8');
  } catch (error) {
    throw new Error(`Failed to read ${normalizePath(path.relative(ROOT, outputPath))}: ${error.message}`);
  }

  if (current !== expected) {
    throw new Error(`${normalizePath(path.relative(ROOT, outputPath))} is out of date; run npm run command-registry:write`);
  }
}

function formatTextSummary(registry) {
  const lines = [
    'Command registry statistics',
    '',
    `Total commands: ${registry.totalCommands}`,
    '',
    'By type:',
  ];

  for (const [type, count] of Object.entries(registry.statistics.byType)) {
    lines.push(`  ${type}: ${count}`);

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Generate the registry first: `node scripts/ci/generate-command-registry.js --write` (or `npm run command-registry:write`).
  2. Commit docs/COMMAND-REGISTRY.json to the repo so --check can read it in CI.
  3. Verify the file path matches DEFAULT_OUTPUT_PATH (docs/COMMAND-REGISTRY.json) and is readable.
  4. In CI, either run --write before --check, or ensure the committed artifact is present.

Example fix

// before — CI runs check on a fresh clone with no committed registry
node scripts/ci/generate-command-registry.js --check
// -> Failed to read docs/COMMAND-REGISTRY.json: ENOENT

// after — generate once, commit, then check
node scripts/ci/generate-command-registry.js --write
git add docs/COMMAND-REGISTRY.json
git commit -m "chore: add command registry"
// CI now passes --check
Defensive patterns

Strategy: try-catch

Validate before calling

const fs = require('fs');
const path = require('path');
const regPath = path.join('docs', 'COMMAND-REGISTRY.json');
if (!fs.existsSync(regPath)) {
  console.error(`${regPath} does not exist. Generate it first:`);
  console.error('  node scripts/ci/generate-command-registry.js --write');
  process.exit(1);
}
try { fs.accessSync(regPath, fs.constants.R_OK); }
catch { console.error(`${regPath} is not readable`); process.exit(1); }

Type guard

function registryReadable(outputPath) {
  try { fs.accessSync(outputPath, fs.constants.R_OK); return true; } catch { return false; }
}

Try / catch

try {
  run(['--check']);
} catch (error) {
  if (/Failed to read.*COMMAND-REGISTRY\.json/i.test(error.message)) {
    console.error('Registry artifact missing. Run: node scripts/ci/generate-command-registry.js --write');
  }
  throw error;
}

Prevention

When it happens

Trigger: Triggered by `node scripts/ci/generate-command-registry.js --check` (or `npm run command-registry:check`) when docs/COMMAND-REGISTRY.json does not exist (never generated), was deleted, is outside the read path, or has restrictive permissions. The check mode requires the file to pre-exist.

Common situations: A fresh clone runs CI before the registry has been generated. The file was gitignored or removed in a cleanup. Permissions were tightened. The docs/ directory was deleted. CI runs --check without a preceding --write step.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/b7c57aa1c4278569. Report an issue: GitHub.