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
- Generate the registry first: `node scripts/ci/generate-command-registry.js --write` (or `npm run command-registry:write`).
- Commit docs/COMMAND-REGISTRY.json to the repo so --check can read it in CI.
- Verify the file path matches DEFAULT_OUTPUT_PATH (docs/COMMAND-REGISTRY.json) and is readable.
- 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
- Always commit docs/COMMAND-REGISTRY.json after generating it — `--check` requires it to exist.
- In CI, run `--write` once (or ensure the committed artifact is present) before `--check`.
- Do not gitignore docs/COMMAND-REGISTRY.json.
- Add a pre-commit hook that runs `--write` when commands/ changes.
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
- ${normalizePath(path.relative(ROOT, outputPath))} is out of
- Unknown argument: ${arg}
- Failed to save package manager config to ${configPath}: ${er
- Multiple ECC repo roots detected: ${uniqueRepoRoots.join(',
- TypeScript compiler not found. Install root dev dependencies
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/b7c57aa1c4278569.
Report an issue: GitHub.