{"record":{"id":"1d6099bd81ae2ee3","repo":"puppetlabs/puppet","slug":"unexpected-output-from-portversion-output","errorCode":null,"errorMessage":"Unexpected output from portversion: %{output}","messagePattern":"Unexpected output from portversion: %(.+?)","errorType":"exception","errorClass":"Puppet::ExecutionFailure","httpStatus":null,"severity":"error","filePath":"lib/puppet/provider/package/portupgrade.rb","lineNumber":156,"sourceCode":"          Puppet.debug \"portupgrade.latest() - Unable to determine new version from (#{otherdata})\"\n          installedversion\n        end\n      when \"?\", \"!\", \"#\"\n        Puppet.debug \"portupgrade.latest() - Comparison Error reported from portversion (#{output})\"\n        installedversion\n      else\n        Puppet.debug \"portupgrade.latest() - Unknown code from portversion output (#{output})\"\n        installedversion\n      end\n\n    elsif output =~ /^\\*\\* No matching package /\n      # error: output not parsed correctly, error out with nil.\n      # Seriously - this section should never be called in a perfect world.\n      # as verification that the port is installed has already happened in query.\n      raise Puppet::ExecutionFailure, _(\"Could not find package %{name}\") % { name: @resource[:name] }\n    else\n      # Any other error (dump output to log)\n      raise Puppet::ExecutionFailure, _(\"Unexpected output from portversion: %{output}\") % { output: output }\n    end\n  end\n\n  ###### Query subcommand - return a hash of details if exists, or nil if it doesn't.\n  # Used to make sure the package is installed\n\n  def query\n    Puppet.debug \"portupgrade.query() - Called on #{@resource[:name]}\"\n\n    cmdline = [\"-qO\", @resource[:name]]\n    begin\n      output = portinfo(*cmdline)\n    rescue Puppet::ExecutionFailure => e\n      raise Puppet::Error.new(output, e)\n    end\n\n    # Check: if output isn't in the right format, return nil\n    if output =~ /^(\\S+)-([^-\\s]+)/","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/provider/package/portupgrade.rb#L138-L174","documentation":"The portupgrade provider's latest could not match portversion output against either the version-status regex or the '** No matching package' marker, so it refuses to guess and raises Puppet::ExecutionFailure including the full raw output. This is a defensive parse failure: the portversion output format is not what the provider understands.","triggerScenarios":"ensure => latest with provider => portupgrade where portversion emits unexpected lines - warnings prepended to output, non-C locale altering messages, or a newer portversion release with different formatting. Both regexes at lib/puppet/provider/package/portupgrade.rb:119 and :149 fail to match.","commonSituations":"LANG/LC_ALL set to a non-C locale on the node; portupgrade suite upgraded to a version with changed output; stderr noise from pkgdb warnings mixed into output.","solutions":["Reproduce manually: 'portversion -v <origin>' and inspect the exact line the provider failed on","Force a stable locale for the run (LANG=C LC_ALL=C in the agent environment) since message formats drift under localization","Update the regexes at lib/puppet/provider/package/portupgrade.rb:119/:149 to match your portversion output and upstream the patch","Migrate to the pkgng provider, which parses 'pkg' output instead"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# Ruby: confirm portversion output matches the shapes the provider parses\nPORTVERSION_LINE = /\\A\\S+-[^-\\s]+\\s+\\S\\s+.*\\z/\ndef portversion_output_parseable?(origin)\n  out = Puppet::Util::Execution.execute(['/usr/local/sbin/portversion', '-v', origin], failonfail: false).to_s\n  out.lines.any? { |l| PORTVERSION_LINE.match?(l) || l =~ /\\A\\*\\* No matching package / }\nend","typeGuard":null,"tryCatchPattern":"begin\n  desired = provider.latest\nrescue Puppet::ExecutionFailure => e\n  Puppet.err(\"Unparseable portversion output for #{resource[:name]}\")\n  desired = provider.query&.fetch(:ensure, :installed)\nend","preventionTips":["Set LANG=C and LC_ALL=C in the agent environment so message formats stay stable","Keep the portupgrade suite at a known version in golden images","Smoke-test 'portversion -v' for managed ports after toolchain upgrades"],"tags":["freebsd","portupgrade","portversion","parse-error","output-format"],"backgroundTag":"command-output-parse-failure","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}