affaan-m/ECC · error · Error

Non-interactive guided install requires at least one…

Error message

Non-interactive guided install requires at least one --harness.

What it means

validateExecutionMode() rejects non-interactive runs that select no harnesses. When stdin is not a TTY the script cannot ask which harnesses to install, so an explicit --harness list (or --all-harnesses) is mandatory. Without it there is nothing to install, so the script aborts before doing any work.

Solutions

  1. Add explicit --harness flags, e.g. --harness claude --harness codex.
  2. Or pass --all-harnesses to select every harness non-interactively.
  3. In CI, ensure the harness list variable is non-empty before invoking the script.

Example fix

// before (non-interactive)
node scripts/install-guided.js --claude-scope project --claude-hooks standard --yes
// after
node scripts/install-guided.js --harness claude --claude-scope project --claude-hooks standard --yes
Defensive patterns

Strategy: validation

Validate before calling

if (!process.stdin.isTTY && harnessFlags.length === 0) { throw new Error('Non-interactive runs need --harness or --all-harnesses'); }

Try / catch

try { await runInstall(args); } catch (e) { if (String(e.message).includes('requires at least one --harness')) { console.error('Add --harness <id> or --all-harnesses for non-interactive use'); process.exit(2); } throw e; }

Prevention

When it happens

Trigger: Running the guided install non-interactively (piped stdin, CI, `</dev/null`) without any --harness flag, so selectedHarnessIds(options) returns an empty array.

Common situations: CI pipelines invoking the installer without harness flags; redirecting stdin accidentally (e.g. `install < file`) forcing non-interactive mode; wrapper scripts that drop --harness flags when variables are empty.

Understand the failure class

Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/cc9ab92d70403aaf. Report an issue: GitHub.

Appendix: source

Thrown at scripts/install-guided.js:189

  return {
    ...options,
    harnesses: normalizedHarnesses,
    claudeScope,
    claudeHooks,
    profile,
  };
}

function selectedHarnessIds(options) {
  if (options.allHarnesses) return normalizeHarnessSelection(['all']);
  if (options.harnesses.length === 0) return [];
  return normalizeHarnessSelection(options.harnesses);
}

function validateExecutionMode(options, interactive) {
  const harnesses = selectedHarnessIds(options);
  if (!interactive && harnesses.length === 0) {
    throw new Error('Non-interactive guided install requires at least one --harness.');
  }
  const requiresExplicit = !interactive || options.json;
  if (requiresExplicit && harnesses.includes('claude') && (!options.claudeScope || !options.claudeHooks)) {
    throw new Error('Claude requires explicit --claude-scope and --claude-hooks choices in this mode.');
  }
  if (requiresExplicit && harnesses.includes('kimi') && !options.profile) {
    throw new Error('Kimi requires an explicit --profile choice in this mode.');
  }
  if ((!interactive || options.json) && !options.yes && !options.dryRun) {
    throw new Error('Non-interactive and JSON mutations require --yes.');
  }
}

function printPlan(plan, output) {
  output.write('\nECC guided install preview\n\n');
  output.write('Harness       Channel           Destination\n');
  for (const entry of plan.harnesses) {
    const harness = getHarnessCapability(entry.id);

View on GitHub (pinned to 8321021c54)