{"record":{"id":"84920ce2b805105f","repo":"go-task/task","slug":"no-terminal","errorCode":null,"errorMessage":"no terminal","messagePattern":"no terminal","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/logger/logger.go","lineNumber":21,"sourceCode":"import (\n\t\"bufio\"\n\t\"io\"\n\t\"slices\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/Ladicle/tabwriter\"\n\t\"github.com/fatih/color\"\n\n\t\"github.com/go-task/task/v3/errors\"\n\t\"github.com/go-task/task/v3/experiments\"\n\t\"github.com/go-task/task/v3/internal/env\"\n\t\"github.com/go-task/task/v3/internal/term\"\n)\n\nvar (\n\tErrPromptCancelled = errors.New(\"prompt cancelled\")\n\tErrNoTerminal      = errors.New(\"no terminal\")\n)\n\nvar (\n\tattrsReset       = envColor(\"COLOR_RESET\", color.Reset)\n\tattrsFgBlue      = envColor(\"COLOR_BLUE\", color.FgBlue)\n\tattrsFgGreen     = envColor(\"COLOR_GREEN\", color.FgGreen)\n\tattrsFgCyan      = envColor(\"COLOR_CYAN\", color.FgCyan)\n\tattrsFgYellow    = envColor(\"COLOR_YELLOW\", color.FgYellow)\n\tattrsFgMagenta   = envColor(\"COLOR_MAGENTA\", color.FgMagenta)\n\tattrsFgRed       = envColor(\"COLOR_RED\", color.FgRed)\n\tattrsFgHiBlue    = envColor(\"COLOR_BRIGHT_BLUE\", color.FgHiBlue)\n\tattrsFgHiGreen   = envColor(\"COLOR_BRIGHT_GREEN\", color.FgHiGreen)\n\tattrsFgHiCyan    = envColor(\"COLOR_BRIGHT_CYAN\", color.FgHiCyan)\n\tattrsFgHiYellow  = envColor(\"COLOR_BRIGHT_YELLOW\", color.FgHiYellow)\n\tattrsFgHiMagenta = envColor(\"COLOR_BRIGHT_MAGENTA\", color.FgHiMagenta)\n\tattrsFgHiRed     = envColor(\"COLOR_BRIGHT_RED\", color.FgHiRed)\n)\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/go-task/task/blob/385e5ad92af02877b6d7cf9dcc963b5ed916e70a/internal/logger/logger.go#L3-L39","documentation":"ErrNoTerminal is a sentinel error exported by the logger package. The Executor's Logger.Prompt (used for interactive confirmations, e.g. prompts declared with `prompt:` in a task) refuses to ask a question when it cannot read an interactive answer: if AssumeTerm is false and term.IsTerminal() reports that stdin is not a TTY, it returns ErrNoTerminal instead of blocking forever on piped input. Callers such as the Executor translate it into TaskCancelledNoTerminalError, treating the task as cancelled.","triggerScenarios":"Running a task that declares `prompt:` (or otherwise calls Logger.Prompt) in an environment where stdin is not a terminal: CI pipelines, `task <...> | cat`, output redirection, nohup/daemon contexts, or pipes like `echo y | task ...` — unless the --assume-terminal (-a) flag / AssumeTerm is set or --yes (-y) is used to skip prompts.","commonSituations":"CI jobs (GitHub Actions, GitLab CI) running destructive tasks guarded by prompts; scripts that pipe or redirect task's stdin; running inside docker exec without -t; cron jobs. Users often hit it after upgrading tasks to add a prompt without updating their automation to pass -y/-a.","solutions":["Run the command with --yes (-y) to auto-approve prompts non-interactively","Run with --assume-terminal (-a) if stdin really is interactive but detection fails (e.g. some CI/PTY setups)","Remove or gate the `prompt:` declaration in the task for non-interactive environments","Restructure the pipeline so task's stdin is a real TTY (e.g. avoid piping into `task`)"],"exampleFix":"// before (CI)\nrun: task deploy\n// after\ndeploy-job:\n  runs-on: ubuntu-latest\n  steps:\n    - run: task deploy --yes","handlingStrategy":"try-catch","validationCode":"// Guard in a wrapper around task execution when stdin may not be a TTY (Go)\nif term.IsTerminal(int(os.Stdin.Fd())) {\n    return runTask(args...) // prompts will work\n}\n// else run with -y or skip tasks that declare prompt:","typeGuard":"func isInteractive() bool {\n\treturn term.IsTerminal(int(os.Stdin.Fd()))\n}","tryCatchPattern":"if err := e.Logger.Prompt(logger.Yellow, p, \"n\", \"y\", \"yes\"); err != nil {\n    if errors.Is(err, logger.ErrNoTerminal) {\n        return &errors.TaskCancelledNoTerminalError{TaskName: call.Task} // handle non-TTY\n    }\n    if errors.Is(err, logger.ErrPromptCancelled) { /* user said no */ }\n    return err\n}","preventionTips":["Always pass --yes (-y) in CI/non-interactive environments","Use --assume-terminal (-a) when running under a PTY wrapper that detection misses","Avoid piping stdin into `task` for tasks that declare prompts","Inventory Taskfiles for `prompt:` declarations before wiring up automation"],"tags":["go-task","terminal","tty","non-interactive","ci"],"backgroundTag":"no-tty-stdin","analyzedSha":"385e5ad92af02877b6d7cf9dcc963b5ed916e70a","analyzedAt":"2026-09-05T09:01:05.226Z","contentChangedAt":"2026-09-05T09:01:05.226Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}