{"record":{"id":"d3d09d23f4c9fe17","repo":"puppetlabs/puppet","slug":"execution-of-str-returned-exit-status-o","errorCode":null,"errorMessage":"Execution of '%{str}' returned %{exit_status}: %{output}","messagePattern":"Execution of '%(.+?)' returned %(.+?): %(.+?)","errorType":"exception","errorClass":"Puppet::ExecutionFailure","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/execution.rb","lineNumber":312,"sourceCode":"            rescue\n              nil\n            end\n          }\n          exit_status = Puppet::Util::Windows::Process.wait_process(process_info.process_handle)\n\n          # read output in if required\n          unless options[:squelch]\n            output = wait_for_output(stdout)\n            Puppet.warning _(\"Could not get output\") unless output\n          end\n        ensure\n          FFI::WIN32.CloseHandle(process_info.process_handle)\n          FFI::WIN32.CloseHandle(process_info.thread_handle)\n        end\n      end\n\n      if options[:failonfail] and exit_status != 0\n        raise Puppet::ExecutionFailure, _(\"Execution of '%{str}' returned %{exit_status}: %{output}\") % { str: command_str, exit_status: exit_status, output: output.strip }\n      end\n    ensure\n      # Make sure all handles are closed in case an exception was thrown attempting to execute.\n      [stdin, stdout, stderr].each { |io|\n        begin\n          io.close\n        rescue\n          nil\n        end\n      }\n      unless options[:squelch]\n        # if we opened a pipe, we need to clean it up.\n        reader.close if reader\n        stdout.close! if stdout && Puppet::Util::Platform.windows?\n      end\n    end\n\n    Puppet::Util::Execution::ProcessOutput.new(output || '', exit_status)","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/execution.rb#L294-L330","documentation":"On Windows, Puppet::Util.execute launches the process via the Win32 API and collects its exit status; when failonfail is true and the status is non-zero it raises Puppet::ExecutionFailure including the command string, the numeric exit status, and the stripped stdout/stderr output. It is the Windows counterpart of the POSIX ExecutionFailure and carries the same meaning: the external command failed.","triggerScenarios":"Running a failing .bat/.exe/PowerShell command through Puppet on Windows with the default failonfail: true — net.exe returning 2, msiexec returning 1603, or a PowerShell one-liner exiting with a script-set code.","commonSituations":"Windows package installs (msiexec error codes), net/user commands failing due to missing privileges, batch scripts that exit non-zero by design, and running under a restricted service account.","solutions":["Re-run the exact command in the same shell as the same account and check %ERRORLEVEL% to see the real failure","Rescue Puppet::ExecutionFailure and branch on the exit code embedded in the message text","Pass failonfail: false when non-zero exits are an expected outcome and inspect the output","Run the agent/service under an account with the privileges the command needs"],"exampleFix":"# before\nPuppet::Util.execute('net localgroup Developers alice /add')\n# => Puppet::ExecutionFailure: Execution of 'net localgroup ...' returned 2: The account already exists ...\n\n# after\nbegin\n  Puppet::Util.execute('net localgroup Developers alice /add')\nrescue Puppet::ExecutionFailure => e\n  code = e.message[/returned (\\d+):/, 1]&.to_i\n  raise unless [0, 1378].include?(code) # 1378 = already a member\nend","handlingStrategy":"try-catch","validationCode":"unless Puppet::Util.which('net.exe')\n  raise ArgumentError, 'net.exe not found on PATH'\nend","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Util.execute(cmd)\nrescue Puppet::ExecutionFailure => e\n  code = e.message[/returned (\\d+):/, 1]&.to_i\n  raise unless [0, 2].include?(code)\nend","preventionTips":["Rescue Puppet::ExecutionFailure on Windows; the exit code is embedded in the message text","Test commands interactively as the same account the Puppet service runs under","Use failonfail: false for commands where failure is an expected branch"],"tags":["execution","subprocess","windows","exit-code","puppet"],"backgroundTag":"non-zero-exit-code","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}