{"record":{"id":"fca65c124ef53ca6","repo":"puppetlabs/puppet","slug":"launchctl-list-failed-to-return-any-data","errorCode":null,"errorMessage":"launchctl list failed to return any data.","messagePattern":"launchctl list failed to return any data\\.","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/provider/service/launchd.rb","lineNumber":190,"sourceCode":"        if by_label.has_key? label\n          { label => by_label[label] }\n        else\n          raise Puppet::Error, \"Unable to find launchd plist for job: #{label}\"\n        end\n      end\n    else\n      # caller wants the whole map\n      by_label\n    end\n  end\n\n  # This status method lists out all currently running services.\n  # This hash is returned at the end of the method.\n  def self.job_list\n    @job_list = Hash.new\n    begin\n      output = launchctl :list\n      raise Puppet::Error, \"launchctl list failed to return any data.\" if output.nil?\n\n      output.split(\"\\n\").each do |line|\n        @job_list[line.split(/\\s/).last] = :running\n      end\n    rescue Puppet::ExecutionFailure => e\n      raise Puppet::Error.new(\"Unable to determine status of #{resource[:name]}\", e)\n    end\n    @job_list\n  end\n\n  # Read a plist, whether its format is XML or in Apple's \"binary1\"\n  # format.\n  def self.read_plist(path)\n    Puppet::Util::Plist.read_plist_file(path)\n  end\n\n  # Read overrides plist, retrying if necessary\n  def self.read_overrides","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/provider/service/launchd.rb#L172-L208","documentation":"The launchd provider's job_list class method runs launchctl list and immediately raises if the command produced nil output (execute returned nothing at all, distinct from an empty-but-successful string). A separate rescue converts Puppet::ExecutionFailure into 'Unable to determine status'. The nil check exists because the code then calls output.split, which would otherwise raise NoMethodError.","triggerScenarios":"Calling self.job_list (status/prefetch paths of the launchd provider) in an environment where the launchctl binary resolves but returns nothing — a broken/shadowed launchctl, an execution wrapper swallowing output, or a non-macOS sandbox where the provider was forced via provider => 'launchd'.","commonSituations":"Running puppet inside CI containers or over a non-macOS test host with the provider forced for spec runs; macOS images where launchctl is damaged or SIP/permissions block it; wrapper scripts in PATH intercepting system binaries.","solutions":["Run launchctl list as the same user puppet uses and confirm it prints lines","Stop forcing provider => 'launchd' on non-macOS nodes; let the provider confine to darwin pick it","Check which launchctl resolves: which -a launchctl, and remove wrappers that eat stdout","Repair the OS binary / reimage broken hosts rather than suppressing the error"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"out=$(launchctl list 2>&1)\nif [ -z \"$out\" ]; then echo \"launchctl returned no data — repair OS or stop forcing launchd provider\"; fi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Let provider confines choose launchd only on darwin; never hardcode provider => 'launchd' in shared profiles","Keep PATH for the agent free of wrapper scripts shadowing system binaries","Include a launchctl sanity probe in macOS host acceptance checks"],"tags":["puppet","launchd","macos","launchctl","empty-output"],"backgroundTag":"empty-command-output","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}