hashicorp/vagrant · error · Vagrant::Errors::UIExpectsTTY
Vagrant is attempting to interface with the UI in a way that
Error message
Vagrant is attempting to interface with the UI in a way that requires a TTY. Most actions in Vagrant that require a TTY have configuration switches to disable this requirement. Please do that or run Vagrant with TTY.
What it means
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.
Source
Thrown at lib/vagrant/ui.rb:175
end
# Use some light meta-programming to create the various methods to
# output text to the UI. These all delegate the real functionality
# to `say`.
[:detail, :info, :warn, :error, :output, :success].each do |method|
class_eval <<-CODE
def #{method}(message, **opts)
super(message)
say(#{method.inspect}, message, **opts)
end
CODE
end
def ask(message, **opts)
super(message)
# We can't ask questions when the output isn't a TTY.
raise Errors::UIExpectsTTY if !@stdin.tty? && !Vagrant::Util::Platform.windows?
# Setup the options so that the new line is suppressed
opts ||= {}
opts[:echo] = true if !opts.key?(:echo)
opts[:new_line] = false if !opts.key?(:new_line)
opts[:prefix] = false if !opts.key?(:prefix)
# Output the data
say(:info, message, opts)
input = nil
if opts[:echo] || !@stdin.respond_to?(:noecho)
input = @stdin.gets
else
begin
input = @stdin.noecho(&:gets)
# Output a newline because without echo, the newline isn'tView on GitHub (pinned to 35f3160f4a)
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)
Example fix
# before (plugin code, fails in CI)
answer = env.ui.ask("Overwrite box? ")
# after
answer = if $stdin.tty?
env.ui.ask("Overwrite box? ")
else
opts[:force] ? "y" : raise("non-interactive run requires --force")
end Defensive patterns
Strategy: validation
Validate before calling
# before calling a prompting API
require 'vagrant/util/platform'
def interactive?
$stdin.tty? || Vagrant::Util::Platform.windows?
end
answer = interactive? ? env.ui.ask('Overwrite? ') : default_answer Try / catch
begin
env.ui.ask('Continue? ')
rescue Vagrant::Errors::UIExpectsTTY
env.ui.info('Non-interactive run; using default')
default
end Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Download to global Vagrant location already in progress. Thi
- You requested to remove the box '%{name}' version '%{version
- The box you're attempting to add already exists. Remove it b
- An invalid option was specified. The help for this command i
- A Vagrant environment or target machine is required to run t
AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21).
Data as JSON: /api/errors/67ba66ed9d1b1549.
Report an issue: GitHub.