affaan-m/ECC · error

${program} ${args.join(' ')} failed${stderr ? `: ${stderr}`

Error message

${program} ${args.join(' ')} failed${stderr ? `: ${stderr}` : ''}

What it means

Thrown by runCommand() after spawnSync returns a non-zero exit status. The function wraps external programs (git, tmux) used by the orchestrator, and the error message includes the program, the joined args, and (if any) trimmed stderr so the caller can see the underlying tool's complaint. spawnSync's own spawn errors (binary not found) are re-thrown directly as result.error before this check.

Source

Thrown at scripts/lib/tmux-worktree-orchestrator.js:336

    for (const file of artifacts.files) {
      fs.writeFileSync(file.path, file.content + '\n', 'utf8');
    }
  }
}

function runCommand(program, args, options = {}) {
  const result = spawnSync(program, args, {
    cwd: options.cwd,
    encoding: 'utf8',
    stdio: ['ignore', 'pipe', 'pipe']
  });

  if (result.error) {
    throw result.error;
  }
  if (result.status !== 0) {
    const stderr = (result.stderr || '').trim();
    throw new Error(`${program} ${args.join(' ')} failed${stderr ? `: ${stderr}` : ''}`);
  }
  return result;
}

function commandSucceeds(program, args, options = {}) {
  const result = spawnSync(program, args, {
    cwd: options.cwd,
    encoding: 'utf8',
    stdio: ['ignore', 'pipe', 'pipe']
  });
  return result.status === 0;
}

function canonicalizePath(targetPath) {
  const resolvedPath = path.resolve(targetPath);

  try {
    return fs.realpathSync.native(resolvedPath);

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Read the stderr in the message — it usually contains the exact tool complaint (e.g. 'fatal: ...').
  2. For 'git worktree add' failures, run git worktree prune --expire now and check for an existing worktree at the target path.
  3. For 'git branch -D' failures, switch off the branch first or use worktree remove which handles the association.
  4. For tmux errors, verify the server with tmux ls and confirm the session name.
  5. Prefer the orchestrator's cleanupExisting/replaceExisting flow over hand-rolled git commands when re-running.

Example fix

// before (manual)
runCommand('git', ['worktree', 'add', '-b', branch, path, 'main']);
// if 'main' does not exist locally: git worktree add ... failed: fatal: invalid reference: main

// after
runCommand('git', ['fetch', 'origin', 'main:main'], { cwd: repoRoot });
runCommand('git', ['worktree', 'add', '-b', branch, path, 'main'], { cwd: repoRoot });
// or pass replaceExisting: true and let executePlan clean up the prior run
Defensive patterns

Strategy: try-catch

Validate before calling

function runCommandOrExplain(program, args, options = {}) {
  const result = require('child_process').spawnSync(program, args, {
    cwd: options.cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
  });
  if (result.status === 0) return result;
  const stderr = (result.stderr || '').trim();
  throw new Error(`${program} ${args.join(' ')} exited ${result.status}: ${stderr}`);
}

// pre-flight checks
if (!runCommand('git', ['rev-parse', '--is-inside-work-tree'], { cwd: repoRoot })) {
  throw new Error(`${repoRoot} is not a git working tree`);
}

Type guard

function commandSucceeds(program, args, options = {}) {
  const result = require('child_process').spawnSync(program, args, {
    cwd: options.cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
  });
  return result.status === 0;
}

Try / catch

try {
  runCommand('git', ['worktree', 'add', '-b', branch, path, baseRef], { cwd: repoRoot });
} catch (error) {
  if (/git worktree add .* failed/.test(error.message)) {
    // try to recover: prune and retry once with a fresh path
    runCommand('git', ['worktree', 'prune', '--expire', 'now'], { cwd: repoRoot });
    runCommand('git', ['worktree', 'add', '-b', branch, path, baseRef], { cwd: repoRoot });
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: runCommand('git', ['worktree', 'add', '-b', branch, path, baseRef]) when baseRef does not exist; runCommand('git', ['branch', '-D', name]) on a branch that is currently checked out; runCommand('tmux', ['kill-session', '-t', name]) when no such session exists; runCommand('git', ['rev-parse', '--is-inside-work-tree']) outside a git repo; tmux subcommand fails because the server is not running.

Common situations: Calling executePlan outside a git working tree; baseRef configured to a branch that does not exist locally; a previous orchestrator run left state that conflicts; tmux not installed or not on PATH (though that usually surfaces as result.error first); permissions issue on the worktree root.

Related errors


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