hashicorp/vagrant · error · Vagrant::Errors::TriggersBadExitCodes

A script exited with an unacceptable exit code %{code}.

Error message

A script exited with an unacceptable exit code %{code}.

What it means

A trigger's `run` script finished with an exit code not in the trigger's allowed exit_codes list (default [0]), so run_script raised TriggersBadExitCodes (lib/vagrant/plugin/v2/trigger.rb:280). With the default `on_error: :halt` the error is re-raised after the script's output, aborting the vagrant command; with `on_error: :continue` Vagrant logs the failure and continues instead. %{code} is the script's actual exit status.

Source

Thrown at lib/vagrant/plugin/v2/trigger.rb:280

            else
              exec_method = Vagrant::Util::PowerShell.method(:execute)
            end
          end

          begin
            result = exec_method.call(*cmd, :notify => [:stdout, :stderr]) do |type,data|
              options = {}
              case type
              when :stdout
                options[:color] = :green if !config.keep_color
              when :stderr
                options[:color] = :red if !config.keep_color
              end

              @ui.detail(data, **options)
            end
            if !exit_codes.include?(result.exit_code)
              raise Errors::TriggersBadExitCodes,
                code: result.exit_code
            end
          rescue => e
            @ui.error(I18n.t("vagrant.errors.triggers_run_fail"))
            @ui.error(e.message)

            if on_error == :halt
              @logger.debug("Trigger run encountered an error. Halting on error...")
              raise e
            else
              @logger.debug("Trigger run encountered an error. Continuing on anyway...")
              @ui.warn(I18n.t("vagrant.trigger.on_error_continue"))
            end
          end
        end

        # Runs a script on the guest
        #

View on GitHub (pinned to 35f3160f4a)

Solutions

  1. Run the script manually the way Vagrant does (bash -c from the project root) and fix whatever makes it exit non-zero
  2. If the non-zero code is expected, whitelist it on the trigger: t.exit_codes = [0, 1]
  3. If failure is acceptable for this workflow, set t.on_error = :continue
  4. Debug with VAGRANT_LOG=debug to see the exact executed command and its output

Example fix

# before
trigger.after :up do |t|
  t.run = { inline: "./check.sh" }  # check.sh exits 1 on warnings
end

# after
trigger.after :up do |t|
  t.run = { inline: "./check.sh" }
  t.exit_codes = [0, 1]   # 1 means warning, not failure
end
Defensive patterns

Strategy: validation

Validate before calling

ok = system("bash", "-c", "./check.sh", out: File::NULL, err: File::NULL)
code = $?.exitstatus
abort "trigger script exits #{code}; whitelist it via exit_codes or fix the script" unless code.zero?

Try / catch

begin
  env.cli(:up)
rescue Vagrant::Errors::TriggersBadExitCodes => e
  warn "trigger script failed with exit code #{e.extra_data[:code]}"
end

Prevention

When it happens

Trigger: A Vagrantfile trigger like `trigger.after :up do |t| t.run = {inline: "./script.sh"} end` where script.sh exits 1 — including the shell's 127 for a missing script and 126 for a non-executable file — and the code is not whitelisted via t.exit_codes.

Common situations: Scripts that use non-zero exits for warnings (grep-style); forgetting chmod +x; paths assumed wrong relative to the project root; scripts depending on env vars absent in the trigger context; Windows batch exit codes.

Related errors


AI-assisted analysis of hashicorp/vagrant@35f3160f4a (2026-08-21). Data as JSON: /api/errors/e682bcf2829d7d3f. Report an issue: GitHub.