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
- Pass the mode and required flags non-interactively: `ecc setup --mode claude-plugin --scope project --yes`.
- Add --hooks if your run requires that choice, e.g. --hooks standard.
- 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
- In CI/Docker, never run bare `ecc setup`; always pass --mode and flags.
- Check isTTY in wrapper scripts and fall back to explicit flags.
- Avoid piping setup stdout/stdin if you want guided mode.
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
- Non-interactive setup requires --yes.
- Claude requires explicit --claude-scope and --claude-hooks…
- Kimi requires an explicit --profile choice in this mode.
- Non-interactive and JSON mutations require --yes.
- Non-interactive guided install requires at least one…
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)