{"record":{"id":"67ba66ed9d1b1549","repo":"hashicorp/vagrant","slug":"vagrant-is-attempting-to-interface-with-the-ui-in","errorCode":null,"errorMessage":"Vagrant is attempting to interface with the UI in a way that requires\na TTY. Most actions in Vagrant that require a TTY have configuration\nswitches to disable this requirement. Please do that or run Vagrant\nwith TTY.","messagePattern":"Vagrant is attempting to interface with the UI in a way that requires\na TTY\\. Most actions in Vagrant that require a TTY have configuration\nswitches to disable this requirement\\. Please do that or run Vagrant\nwith TTY\\.","errorType":"exception","errorClass":"Vagrant::Errors::UIExpectsTTY","httpStatus":null,"severity":"error","filePath":"lib/vagrant/ui.rb","lineNumber":175,"sourceCode":"      end\n\n      # Use some light meta-programming to create the various methods to\n      # output text to the UI. These all delegate the real functionality\n      # to `say`.\n      [:detail, :info, :warn, :error, :output, :success].each do |method|\n        class_eval <<-CODE\n          def #{method}(message, **opts)\n            super(message)\n            say(#{method.inspect}, message, **opts)\n          end\n        CODE\n      end\n\n      def ask(message, **opts)\n        super(message)\n\n        # We can't ask questions when the output isn't a TTY.\n        raise Errors::UIExpectsTTY if !@stdin.tty? && !Vagrant::Util::Platform.windows?\n\n        # Setup the options so that the new line is suppressed\n        opts ||= {}\n        opts[:echo]     = true  if !opts.key?(:echo)\n        opts[:new_line] = false if !opts.key?(:new_line)\n        opts[:prefix]   = false if !opts.key?(:prefix)\n\n        # Output the data\n        say(:info, message, opts)\n\n        input = nil\n        if opts[:echo] || !@stdin.respond_to?(:noecho)\n          input = @stdin.gets\n        else\n          begin\n            input = @stdin.noecho(&:gets)\n\n            # Output a newline because without echo, the newline isn't","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/lib/vagrant/ui.rb#L157-L193","documentation":"Raised by Vagrant's interactive UI layer when ui.ask is called and stdin is not a TTY on a non-Windows host (the guard is `raise Errors::UIExpectsTTY if !@stdin.tty? && !Vagrant::Util::Platform.windows?`). Vagrant asks questions (confirmations, credentials) by printing a prompt and reading stdin, which requires a real terminal. The check runs before any input is read, so the process fails fast instead of hanging.","triggerScenarios":"Any code path calling env.ui.ask / ui.ask (plugin commands, provider or box-add prompts) when Vagrant's stdin is piped, redirected, or detached: `vagrant up < /dev/null`, CI runners, cron, Docker containers, nohup. Windows hosts are explicitly exempt from the check.","commonSituations":"Running Vagrant in CI (Jenkins/GitLab), inside containers, or from automation where a plugin attempts to prompt; invoking vagrant via a daemon or service wrapper with no controlling terminal.","solutions":["Run the command from an interactive terminal or allocate a pseudo-TTY (e.g. `script -qec \"vagrant up\" /dev/null` or a pty wrapper)","Remove the need for the prompt: pass the non-interactive switch the prompt supports (e.g. `--force`, pre-set credentials) so the ask path is never hit","If you own the calling code, call ui.ask only when stdin is a TTY and use a safe default otherwise","Remember the check cannot fire on Windows; if you see it on Windows tooling, the actual runtime is a non-Windows wrapper (WSL, ssh session)"],"exampleFix":"# before (plugin code, fails in CI)\nanswer = env.ui.ask(\"Overwrite box? \")\n\n# after\nanswer = if $stdin.tty?\n  env.ui.ask(\"Overwrite box? \")\nelse\n  opts[:force] ? \"y\" : raise(\"non-interactive run requires --force\")\nend","handlingStrategy":"validation","validationCode":"# before calling a prompting API\nrequire 'vagrant/util/platform'\n\ndef interactive?\n  $stdin.tty? || Vagrant::Util::Platform.windows?\nend\n\nanswer = interactive? ? env.ui.ask('Overwrite? ') : default_answer","typeGuard":null,"tryCatchPattern":"begin\n  env.ui.ask('Continue? ')\nrescue Vagrant::Errors::UIExpectsTTY\n  env.ui.info('Non-interactive run; using default')\n  default\nend","preventionTips":["Treat ui.ask as interactive-only API; gate it on $stdin.tty?","Give every custom command a non-interactive flag or env override","In CI, allocate a pty or pre-supply answers via configuration"],"tags":["tty","interactive","stdin","cli","ci"],"backgroundTag":"operation-requires-tty","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}