{"record":{"id":"7c487c7939d36c85","repo":"puppetlabs/puppet","slug":"output-to-s","errorCode":null,"errorMessage":"output.to_s","messagePattern":"output\\.to_s","errorType":"exception","errorClass":"Puppet::ExecutionFailure","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/execution.rb","lineNumber":88,"sourceCode":"      debug \"Executing '#{command_str}'\"\n    else\n      Puppet.debug { \"Executing '#{command_str}'\" }\n    end\n\n    # force the run of the command with\n    # the user/system locale to \"C\" (via environment variables LANG and LC_*)\n    # it enables to have non localized output for some commands and therefore\n    # a predictable output\n    english_env = ENV.to_hash.merge({ 'LANG' => 'C', 'LC_ALL' => 'C' })\n    output = Puppet::Util.withenv(english_env) do\n      # We are intentionally using 'pipe' with open to launch a process\n      open(\"| #{command_str} 2>&1\") do |pipe| # rubocop:disable Security/Open\n        yield pipe\n      end\n    end\n\n    if failonfail && exitstatus != 0\n      raise Puppet::ExecutionFailure, output.to_s\n    end\n\n    output\n  end\n\n  def self.exitstatus\n    $CHILD_STATUS.exitstatus\n  end\n  private_class_method :exitstatus\n\n  # Default empty options for {execute}\n  NoOptionsSpecified = {}\n\n  # Executes the desired command, and return the status and output.\n  # def execute(command, options)\n  # @param command [Array<String>, String] the command to execute. If it is\n  #   an Array the first element should be the executable and the rest of the\n  #   elements should be the individual arguments to that executable.","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/execution.rb#L70-L106","documentation":"Puppet::Util.execute runs a command with stdout and stderr combined under a C locale (the POSIX pipe path) and, when the failonfail option is true (the default), raises Puppet::ExecutionFailure if the exit status is non-zero. The exception message is simply the command's captured output (output.to_s). This is Puppet's standard mechanism for surfacing a failing external command.","triggerScenarios":"Calling Puppet::Util.execute('systemctl reload nginx') (failonfail defaults to true) where the command exists but exits non-zero: a package manager returning 100, a validation command rejecting input, a service control command failing, and so on.","commonSituations":"Providers and exec-style code invoking CLI tools that fail on bad input, commands behaving differently as root versus another user, PATH differences causing a different binary to run, and callers that do not expect any non-zero exit.","solutions":["Re-run the failing command manually as the same user with the same environment; the real error is in the exception message (the combined output)","Pass failonfail: false when a non-zero exit is expected, and branch on the returned output or exit status instead","Rescue Puppet::ExecutionFailure explicitly at the call site and handle it","Control the environment (PATH, locale) via the execute options so the intended command runs"],"exampleFix":"# before\nPuppet::Util.execute(['/usr/sbin/useradd', '-m', 'bob'])\n# => Puppet::ExecutionFailure: useradd: user 'bob' already exists\n\n# after\nbegin\n  Puppet::Util.execute(['/usr/sbin/useradd', '-m', 'bob'])\nrescue Puppet::ExecutionFailure => e\n  raise unless e.message.include?('already exists')\nend","handlingStrategy":"try-catch","validationCode":"unless Puppet::Util.which('systemctl')\n  raise ArgumentError, 'systemctl not found on PATH'\nend\nPuppet::Util.execute(['systemctl', 'is-active', 'nginx'], failonfail: false)","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Util.execute(cmd)\nrescue Puppet::ExecutionFailure => e\n  Puppet.err(\"Command failed: #{e.message}\")\n  raise unless e.message.include?('already exists')\nend","preventionTips":["Rescue Puppet::ExecutionFailure wherever a non-zero exit is a normal outcome","Use failonfail: false plus explicit output checks for commands whose failure is expected","Verify the binary exists with Puppet::Util.which before executing"],"tags":["execution","subprocess","exit-code","posix","puppet"],"backgroundTag":"non-zero-exit-code","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}