puppetlabs/puppet · error · Puppet::Error

Could not match version info '%{info}'

Error message

Could not match version info '%{info}'

What it means

Raised by the FreeBSD 'ports' provider's latest method when 'portversion -v' output cannot be parsed. After deciding the port needs updating (comparison char is not '=' or '>'), the trailing info field must match '\((\w+) has (.+)\)'; when it does not, Puppet raises this error including the raw info text. It almost always means the portversion output format changed or the ports/pkgdb metadata is stale.

Source

Thrown at lib/puppet/provider/package/ports.rb:61

    match = Regexp.last_match(2)
    info = Regexp.last_match(3)

    unless pkgstuff =~ /^\S+-([^-\s]+)$/
      raise Puppet::Error,
            _("Could not match package info '%{pkgstuff}'") % { pkgstuff: pkgstuff }
    end

    version = Regexp.last_match(1)

    if match == "=" or match == ">"
      # we're up to date or more recent
      return version
    end

    # Else, we need to be updated; we need to pull out the new version

    unless info =~ /\((\w+) has (.+)\)/
      raise Puppet::Error,
            _("Could not match version info '%{info}'") % { info: info }
    end

    source = Regexp.last_match(1)
    newversion = Regexp.last_match(2)

    debug "Newer version in #{source}"
    newversion
  end

  def query
    # support portorigin_glob such as "mail/postfix"
    name = self.name
    if name =~ %r{/}
      name = self.name.split(%r{/}).slice(1)
    end
    self.class.instances.each do |instance|
      if instance.name == name

View on GitHub (pinned to e227c27540)

Solutions

  1. Run 'portversion -v <origin>' by hand and compare the trailing parenthesized text with the expected '(port has <version>)' form
  2. Refresh metadata: 'portsnap fetch update' then rebuild the package database with 'pkgdb -aFu' so portversion emits current data
  3. Migrate to the pkgng provider on FreeBSD 10+; the portupgrade tooling this provider wraps is legacy
  4. If your portversion release genuinely changed the format, patch the regex at lib/puppet/provider/package/ports.rb:60 and open an upstream Puppet issue

Example fix

// before
package { 'mail/postfix':
  ensure   => latest,
  provider => ports,
}
// after - pkgng is the maintained FreeBSD provider
package { 'mail/postfix':
  ensure   => latest,
  provider => pkgng,
}
Defensive patterns

Strategy: try-catch

Validate before calling

# Ruby: verify portversion emits parseable output before relying on latest
def parseable_portversion_info?(origin)
  out = Puppet::Util::Execution.execute(['/usr/local/sbin/portversion', '-v', origin], failonfail: false).to_s
  line = out.split("\n").last.to_s
  m = line.match(/^(\S+)\s+(\S)\s+(.+)$/)
  !m.nil? && (m[2] =~ /[=>]/ || m[3] =~ /\((\w+) has (.+)\)/)
end

Try / catch

begin
  latest_version = provider.latest
rescue Puppet::Error => e
  Puppet.debug("portversion output unparseable for #{resource[:name]}: #{e.message}")
  latest_version = provider.query&.fetch(:ensure, nil) # fall back to installed version
end

Prevention

When it happens

Trigger: A package resource with provider => ports and ensure => latest (any code path calling latest) where portversion reports '<' but the third output field lacks a '(<source> has <version>)' segment, e.g. output like 'portpkg-1.7_5 < needs updating (=> \'newport/pkg\')'. The regex at lib/puppet/provider/package/ports.rb:60 must match or the error fires.

Common situations: FreeBSD hosts where the ports tree was refreshed but the pkgdb was not rebuilt; portupgrade suite upgrades that changed portversion output formatting; port origins renamed or removed from the ports tree; mixed ports/pkgng systems.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/b5bf3bb55cd9a57a. Report an issue: GitHub.