{"record":{"id":"eabbab5423fb3ffc","repo":"angular/angular-cli","slug":"no-terminal-detected","errorCode":null,"errorMessage":"No terminal detected","messagePattern":"No terminal detected","errorType":"exception","errorClass":"CommandError","httpStatus":null,"severity":"error","filePath":"packages/angular/cli/src/commands/add/cli.ts","lineNumber":578,"sourceCode":"    context.homepage = manifest.homepage;\n\n    if (await this.getPeerDependencyConflicts(manifest)) {\n      task.output = color.yellow(\n        figures.warning +\n          ' Package has unmet peer dependencies. Adding the package may not succeed.',\n      );\n    }\n  }\n\n  private async confirmInstallationTask(\n    context: AddCommandTaskContext,\n    task: AddCommandTaskWrapper,\n  ): Promise<void> {\n    if (!isTTY()) {\n      task.output =\n        `'--skip-confirmation' can be used to bypass installation confirmation. ` +\n        `Ensure package name is correct prior to '--skip-confirmation' option usage.`;\n      throw new CommandError('No terminal detected');\n    }\n\n    const { ListrInquirerPromptAdapter } = await import('@listr2/prompt-adapter-inquirer');\n    const { confirm } = await import('@inquirer/prompts');\n    const shouldProceed = await task.prompt(ListrInquirerPromptAdapter).run(confirm, {\n      message:\n        `The package ${color.blue(context.packageIdentifier.toString())} will be installed and executed.\\n` +\n        'Would you like to proceed?',\n      default: true,\n      theme: { prefix: '' },\n    });\n\n    if (!shouldProceed) {\n      throw new CommandError('Command aborted');\n    }\n  }\n\n  private async cleanUpTemporaryDependency(packageName: string): Promise<void> {","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular/cli/src/commands/add/cli.ts#L560-L596","documentation":"confirmInstallationTask requires an interactive terminal to show the 'Would you like to proceed?' confirmation prompt. If `isTTY()` returns false, the CLI cannot prompt, prints a hint about `--skip-confirmation`, and throws this CommandError instead of hanging or auto-confirming.","triggerScenarios":"Running `ng add <package>` without `--skip-confirmation` in a non-interactive context: CI pipelines, docker builds, scripts/pipes where stdin/stdout is not a TTY.","commonSituations":"CI jobs (GitHub Actions, Jenkins, GitLab CI) running `ng add` in a script; Docker RUN commands; piping output (`ng add x | tee log`); IDE-embedded terminals without TTY emulation.","solutions":["Add `--skip-confirmation` to the `ng add` command when no interactive terminal is available.","Only run `ng add` interactively in a real terminal (not inside scripts/CI) without the flag.","In CI, pre-install the package and invoke the schematic directly (e.g. `ng generate <package>:ng-add`) to avoid the prompt path.","Ensure your terminal emulator allocates a pseudo-TTY if running in a container (`docker run -it`)."],"exampleFix":"// before\nng add @angular/material\n// after\nng add @angular/material --skip-confirmation","handlingStrategy":"validation","validationCode":"if (!process.stdin.isTTY || !process.stdout.isTTY) {\n  args.push('--skip-confirmation'); // must be set before invoking ng add non-interactively\n}","typeGuard":"function isInteractive(env: NodeJS.ProcessEnv = process.env, stdin: { isTTY?: boolean } = process.stdin): boolean {\n  return stdin.isTTY === true && !env.CI;\n}","tryCatchPattern":"try {\n  const args = isInteractive() ? ['add', pkg] : ['add', pkg, '--skip-confirmation'];\n  await exec('ng', args);\n} catch (e) {\n  if (e instanceof Error && e.message === 'No terminal detected') {\n    console.error('ng add requires a TTY; rerun with --skip-confirmation.');\n  }\n  throw e;\n}","preventionTips":["In CI/scripts, always pass --skip-confirmation to ng add.","Detect TTY (process.stdin.isTTY) before launching interactive CLI tools.","Allocate a pseudo-TTY in containers (docker run -it) when prompts are needed.","Avoid piping stdin/stdout when you intend to answer prompts."],"tags":["tty","ci","interactive","angular-cli"],"backgroundTag":"non-interactive-terminal","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}