affaan-m/ECC · error · Error
Usage: legacy-sync-state.js <begin|record|finalize|rollback>
Error message
Usage: legacy-sync-state.js <begin|record|finalize|rollback> [options]
What it means
This is the fall-through usage error at the bottom of main() in scripts/codex/legacy-sync-state.js. If the first positional argument does not equal 'begin', 'record', 'finalize', or 'rollback', none of the if-branches return and the script throws this usage message; the process exits 1 with an '[ecc-sync] ERROR:' prefix. It is the script's only mechanism for listing valid subcommands.
Source
Thrown at scripts/codex/legacy-sync-state.js:54
if (!statePath || !filePath) throw new Error('record requires --state and --path');
recordLegacySyncPath({ statePath, filePath });
return;
}
if (command === 'finalize') {
const statePath = readFlag(argv, '--state');
if (!statePath) throw new Error('finalize requires --state');
finalizeLegacySyncState({ statePath });
return;
}
if (command === 'rollback') {
const statePath = readFlag(argv, '--state');
if (!statePath) throw new Error('rollback requires --state');
const result = rollbackLegacyCodexSync({ statePath });
process.stdout.write(`${JSON.stringify(result)}\n`);
if (result.status !== 'rolled-back') process.exitCode = 1;
return;
}
throw new Error('Usage: legacy-sync-state.js <begin|record|finalize|rollback> [options]');
}
module.exports = { main, readFlag };
if (require.main === module) {
try {
main();
} catch (error) {
process.stderr.write(`[ecc-sync] ERROR: ${error.message}\n`);
process.exit(1);
}
}
View on GitHub (pinned to 06c5e118c4)
Solutions
- Use one of the four subcommands: `node scripts/codex/legacy-sync-state.js <begin|record|finalize|rollback> [options]`
- Put the subcommand first: `begin --state <path>`, not `--state <path> begin`
- Read the top of the file for each subcommand's required flags (begin/rollback: --state; record: --state and --path; finalize: --state)
Example fix
// before node scripts/codex/legacy-sync-state.js sync // after node scripts/codex/legacy-sync-state.js begin --state .codex-sync-state.json
Defensive patterns
Strategy: validation
Validate before calling
const SUBCOMMANDS = new Set(['begin', 'record', 'finalize', 'rollback']);
const cmd = process.argv[2];
if (!SUBCOMMANDS.has(cmd)) {
console.error('Usage: legacy-sync-state.js <begin|record|finalize|rollback> [options]');
process.exit(2);
} Type guard
const isLegacySyncSubcommand = (c) => ['begin', 'record', 'finalize', 'rollback'].includes(c);
Prevention
- Always put the subcommand as the first positional argument
- When wrapping the script programmatically, whitelist subcommands before spawning
When it happens
Trigger: Running the script with no arguments at all; a typo'd subcommand such as `finallize` or `rec`; passing flags before the subcommand (e.g. `--state x finalize`) so argv parsing sees '--state' as the command; passing an extra positional like `node legacy-sync-state.js finalize extra` still works, but any other first token hits the fall-through.
Common situations: Exploring the script without reading its source and guessing subcommand names; shell aliases or npm scripts that prepend flags before the subcommand; automated pipelines invoking the script with an empty argument string.
Related errors
- Invalid ${flag}: expected a single cache path segment
- Unknown argument: ${arg}
- Missing value for ${arg}
- begin requires --codex-home and --backup-dir
- record requires --state and --path
AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18).
Data as JSON: /api/errors/49cdb889ba802a53.
Report an issue: GitHub.