{"record":{"id":"09008d36f808bf44","repo":"affaan-m/ECC","slug":"interactive-setup-requires-a-terminal-pass-mode","errorCode":null,"errorMessage":"Interactive setup requires a terminal. Pass --mode claude-plugin and the required flags.","messagePattern":"Interactive setup requires a terminal\\. Pass --mode claude-plugin and the required flags\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/setup.js","lineNumber":426,"sourceCode":"    const shouldCollectInteractiveChoices = needsInteractiveChoices(options);\n    const needsConfirmation = !options.yes && !options.dryRun;\n    const interactiveDefaults = interactive\n      && (shouldCollectInteractiveChoices || needsConfirmation)\n      ? resolveInteractiveDefaults()\n      : undefined;\n    if (interactive && shouldCollectInteractiveChoices) {\n      terminal = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout,\n      });\n      options = await collectInteractiveOptions(\n        options,\n        interactiveDefaults,\n        terminal\n      );\n    } else if (!options.mode) {\n      if (!interactive) {\n        throw new Error(\n          'Interactive setup requires a terminal. Pass --mode claude-plugin and the required flags.'\n        );\n      }\n    }\n\n    if (interactiveDefaults) {\n      const confirmationAction = interactiveDefaults.multipleScopes\n        ? 'Resume migration'\n        : (\n          interactiveDefaults.installed && interactiveDefaults.scope !== options.scope\n            ? 'Migrate'\n            : 'Apply'\n        );\n      options = {\n        ...options,\n        confirmationAction,\n      };\n    }","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/setup.js#L408-L444","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n# CI script\nnpx ecc setup\n\n// after\n# CI script\nnpx ecc setup --mode claude-plugin --scope project --hooks standard --yes","handlingStrategy":"validation","validationCode":"// Non-TTY guard before invoking bare setup\nif (!process.stdout.isTTY && !argv.includes('--mode')) {\n  throw new Error('Non-interactive shell: pass --mode claude-plugin and required flags.');\n}","typeGuard":"const isInteractive = () => Boolean(process.stdout.isTTY && process.stdin.isTTY);","tryCatchPattern":"try {\n  await runSetup(rawArgs);\n} catch (err) {\n  if (err.message.includes('Interactive setup requires a terminal')) {\n    console.error(err.message);\n    process.exitCode = 2;\n  } else throw err;\n}","preventionTips":["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."],"tags":["cli","non-interactive","tty","ci"],"backgroundTag":"authentication-required","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}