affaan-m/ECC · error

Interactive setup requires a terminal. Pass --mode…

Error message

Interactive setup requires a terminal. Pass --mode claude-plugin and the required flags.

What it means

main throws this when no mode was supplied and the session is not interactive (no usable terminal), e.g. stdin/stdout are piped or closed. Bare `ecc setup` relies on interactive prompting to choose mode/options, which is impossible without a terminal, so the caller must supply --mode claude-plugin plus required flags explicitly.

Solutions

  1. Pass the mode and required flags non-interactively: `ecc setup --mode claude-plugin --scope project --yes`.
  2. Add --hooks if your run requires that choice, e.g. --hooks standard.
  3. Run inside a TTY if you truly want guided setup, or add --dry-run to preview without a terminal.

Example fix

// before
# CI script
npx ecc setup

// after
# CI script
npx ecc setup --mode claude-plugin --scope project --hooks standard --yes
Defensive patterns

Strategy: validation

Validate before calling

// Non-TTY guard before invoking bare setup
if (!process.stdout.isTTY && !argv.includes('--mode')) {
  throw new Error('Non-interactive shell: pass --mode claude-plugin and required flags.');
}

Type guard

const isInteractive = () => Boolean(process.stdout.isTTY && process.stdin.isTTY);

Try / catch

try {
  await runSetup(rawArgs);
} catch (err) {
  if (err.message.includes('Interactive setup requires a terminal')) {
    console.error(err.message);
    process.exitCode = 2;
  } else throw err;
}

Prevention

When it happens

Trigger: Running `ecc setup` in a CI pipeline, via a spawned child process without stdio inherited, or with stdin redirected from /dev/null — any case where interactive is false and options.mode is undefined.

Common situations: CI/CD jobs running bare setup; Docker builds and non-TTY shells; piping output (`ecc setup | tee log`) or running under process managers that detach stdio.

Related errors


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

Appendix: source

Thrown at scripts/setup.js:426

    const shouldCollectInteractiveChoices = needsInteractiveChoices(options);
    const needsConfirmation = !options.yes && !options.dryRun;
    const interactiveDefaults = interactive
      && (shouldCollectInteractiveChoices || needsConfirmation)
      ? resolveInteractiveDefaults()
      : undefined;
    if (interactive && shouldCollectInteractiveChoices) {
      terminal = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
      });
      options = await collectInteractiveOptions(
        options,
        interactiveDefaults,
        terminal
      );
    } else if (!options.mode) {
      if (!interactive) {
        throw new Error(
          'Interactive setup requires a terminal. Pass --mode claude-plugin and the required flags.'
        );
      }
    }

    if (interactiveDefaults) {
      const confirmationAction = interactiveDefaults.multipleScopes
        ? 'Resume migration'
        : (
          interactiveDefaults.installed && interactiveDefaults.scope !== options.scope
            ? 'Migrate'
            : 'Apply'
        );
      options = {
        ...options,
        confirmationAction,
      };
    }

View on GitHub (pinned to 8321021c54)