affaan-m/ECC · error · Error

begin requires --codex-home and --backup-dir

Error message

begin requires --codex-home and --backup-dir

What it means

scripts/codex/legacy-sync-state.js is a small state-machine CLI (begin/record/finalize/rollback) used by the Codex legacy sync to migrate hooks atomically with backup/rollback. `begin` must know where CODEX_HOME lives and where backups are written, so it requires both --codex-home and --backup-dir; readFlag() returns null when a flag is absent, its value is missing, or the next token starts with '--', and any null triggers this throw.

Source

Thrown at scripts/codex/legacy-sync-state.js:24

  finalizeLegacySyncState,
  recordLegacySyncPath,
  rollbackLegacyCodexSync,
} = require('../lib/codex-legacy-sync');

function readFlag(args, name) {
  const index = args.indexOf(name);
  if (index === -1) return null;
  const value = args[index + 1];
  if (!value || value.startsWith('--')) return null;
  return value;
}

function main(argv = process.argv.slice(2)) {
  const command = argv[0];
  if (command === 'begin') {
    const codexHome = readFlag(argv, '--codex-home');
    const backupDir = readFlag(argv, '--backup-dir');
    if (!codexHome || !backupDir) throw new Error('begin requires --codex-home and --backup-dir');
    process.stdout.write(`${beginLegacySyncState({
      codexHome,
      backupDir,
      previousHooksPath: readFlag(argv, '--previous-hooks-path') || '',
      installedHooksPath: readFlag(argv, '--installed-hooks-path'),
    })}\n`);
    return;
  }
  if (command === 'record') {
    const statePath = readFlag(argv, '--state');
    const filePath = readFlag(argv, '--path');
    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');

View on GitHub (pinned to 06c5e118c4)

Solutions

  1. Provide both required flags with values: `node scripts/codex/legacy-sync-state.js begin --codex-home ~/.codex --backup-dir /tmp/ecc-backup`
  2. Keep optional flags (--previous-hooks-path, --installed-hooks-path) after the required pair, each immediately followed by its own value
  3. If a legitimate path starts with '-', express it absolutely (e.g. /home/user/-weird) so it does not look like a flag

Example fix

# before
node scripts/codex/legacy-sync-state.js begin --codex-home ~/.codex
# after
node scripts/codex/legacy-sync-state.js begin --codex-home ~/.codex --backup-dir /tmp/ecc-backup
Defensive patterns

Strategy: validation

Validate before calling

function readFlag(args, name) {
  const i = args.indexOf(name);
  if (i === -1) return null;
  const v = args[i + 1];
  return v && !v.startsWith('--') ? v : null;
}
if (!readFlag(argv, '--codex-home') || !readFlag(argv, '--backup-dir')) {
  throw new Error('begin requires --codex-home and --backup-dir');
}

Type guard

function hasRequiredBeginFlags(argv) {
  const get = n => { const i = argv.indexOf(n); const v = argv[i + 1]; return i !== -1 && v && !v.startsWith('--'); };
  return get('--codex-home') && get('--backup-dir');
}

Try / catch

try {
  main(argv);
} catch (error) {
  if (/^begin requires/.test(error.message)) {
    process.stderr.write('Usage: legacy-sync-state.js begin --codex-home <dir> --backup-dir <dir>\n');
  }
}

Prevention

When it happens

Trigger: Invoking `begin` without one of the two flags; ordering mistakes such as `--backup-dir --previous-hooks-path x` where the value slot holds the next flag; a path argument that itself begins with '--'.

Common situations: Running the helper manually without the full argument set the sync wrapper normally supplies; misordered arguments in wrapper scripts; quoting or variable-expansion mistakes eating a value.

Related errors


AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18). Data as JSON: /api/errors/3a267fd01bc789cf. Report an issue: GitHub.