{"record":{"id":"0393ebb353ee2fc8","repo":"hashicorp/vagrant","slug":"vagrant-trigger-abort","errorCode":null,"errorMessage":"vagrant.trigger.abort","messagePattern":"vagrant\\.trigger\\.abort","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/vagrant/plugin/v2/trigger.rb","lineNumber":352,"sourceCode":"            else\n              @logger.debug(\"Trigger run encountered an error. Continuing on anyway...\")\n              @machine.ui.error(e.message)\n            end\n          end\n        end\n\n        # Exits Vagrant immediately\n        #\n        # @param [Integer] code Code to exit Vagrant on\n        def trigger_abort(exit_code)\n          if Thread.current[:batch_parallel_action]\n            @ui.warn(I18n.t(\"vagrant.trigger.abort_threaded\"))\n            @logger.debug(\"Trigger abort within parallel batch action. \" \\\n              \"Setting exit code and terminating.\")\n            Thread.current[:exit_code] = exit_code\n            Thread.current.terminate\n          else\n            @ui.warn(I18n.t(\"vagrant.trigger.abort\"))\n            @logger.debug(\"Trigger abort within non-parallel action, exiting directly\")\n            Process.exit!(exit_code)\n          end\n        end\n\n        # Calls the given ruby block for execution\n        #\n        # @param [Proc] ruby_block\n        def execute_ruby(ruby_block)\n          ruby_block.call(@env, @machine)\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":334,"sourceCodeEnd":368,"githubUrl":"https://github.com/hashicorp/vagrant/blob/35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5/lib/vagrant/plugin/v2/trigger.rb#L334-L368","documentation":"This is the warning emitted by Vagrant's trigger engine when a Vagrantfile trigger is configured with on_error: :abort (or a Ruby trigger block calls trigger_abort). In the normal (non-parallel) path Vagrant prints 'Vagrant has been configured to abort. Terminating now...' and then hard-exits the process via Process.exit!(exit_code). Inside a parallel batch action (vagrant up --parallel) it instead stores the exit code on the worker thread and terminates just that thread so remaining actions can finish.","triggerScenarios":"A Vagrantfile defines config.trigger.after :up, :on_error => :abort (or a :type => :ruby trigger whose block calls trigger_abort(code)), and the triggered action fails; or you run any command under a batch parallel action (vagrant up with machine_set parallelism) and the trigger fires there.","commonSituations":"Teams adding deploy/test hooks to Vagrantfile triggers that intentionally halt on failure; CI pipelines that expect a specific exit code; users confused why the whole Vagrant process dies (exit! skips at_exit handlers, so cleanup code and tmp files may be skipped) or why under --parallel only one machine aborted while others kept running.","solutions":["If the abort is unintended, change the trigger's on_error behavior: replace :on_error => :abort with :on_error => :continue (or remove it) in the Vagrantfile trigger block.","If the abort is intended but you need cleanup, move cleanup into the trigger itself before calling trigger_abort, because Process.exit! skips Ruby at_exit handlers.","For parallel runs, remember the exit code is per-thread (Thread.current[:exit_code]); check the batch action summary to see which machine aborted rather than expecting an immediate process exit.","Inspect debug logs (LOG_LEVEL=debug vagrant up) for the lines 'Trigger abort within parallel batch action' or 'Trigger abort within non-parallel action' to confirm which path executed."],"exampleFix":"# before\nconfig.trigger.after :up do |trigger|\n  trigger.run = { inline: \"./deploy.sh\" }\n  trigger.on_error = :abort   # any failure kills the whole vagrant process via Process.exit!\nend\n\n# after\nconfig.trigger.after :up do |trigger|\n  trigger.run = { inline: \"./deploy.sh\" }\n  trigger.on_error = :continue # failure is logged, Vagrant keeps going\nend","handlingStrategy":"validation","validationCode":"# Before relying on trigger behavior, dry-run the Vagrantfile config\nrequire \"vagrant\"\n# inspect triggers without executing them:\n#   vagrant validate  (checks Vagrantfile syntax)\n# and grep the Vagrantfile for abort-on-error triggers:\n#   grep -n \"on_error\" Vagrantfile\n# ensure it reads `on_error = :continue` unless a hard abort is intended","typeGuard":null,"tryCatchPattern":"In a Ruby plugin wrapping actions, rescue nothing here: trigger_abort in the non-parallel path calls Process.exit! which cannot be caught (it skips SystemExit handling). Guard instead by checking the configured trigger's on_error value before executing the triggered command.","preventionTips":["Default new triggers to on_error = :continue; opt into :abort deliberately.","Never rely on at_exit cleanup in workflows with :abort triggers — Process.exit! skips it; perform cleanup inside the trigger before aborting.","In parallel batches, check per-machine exit codes from the batch summary, since only the worker thread terminates.","Wrap fragile scripts in the trigger with their own error handling so the trigger itself never fails."],"tags":["vagrant","triggers","process-exit","vagrantfile-config"],"backgroundTag":"config-triggered-abort","analyzedSha":"35f3160f4ad6edc3a9f3aa9570adfc1a4d73aaa5","analyzedAt":"2026-08-21T13:34:32.514Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}