puppetlabs/puppet · error · Puppet::DataBinding::LookupError

The convert_to lookup_option for key '%{key}' raised error:

Error message

The convert_to lookup_option for key '%{key}' raised error: %{msg}

What it means

The second guard in convert_result: the convert_to type parsed fine, but actually applying it — scope.call_function('new', [type, value, *extra_args]) — raised. The new() function could not create an instance of the target type from the found value (e.g. Integer from 'abc', Enum from a non-member, Struct from a hash with wrong keys), or extra convert_to arguments were invalid. The original error message is carried in %{msg} inside Puppet::DataBinding::LookupError.

Source

Thrown at lib/puppet/pops/lookup/lookup_adapter.rb:119

    return result if convert_to.nil?

    convert_to = convert_to.is_a?(Array) ? convert_to : [convert_to]
    if convert_to[0].is_a?(String)
      begin
        convert_to[0] = Puppet::Pops::Types::TypeParser.singleton.parse(convert_to[0])
      rescue StandardError => e
        raise Puppet::DataBinding::LookupError,
              _("Invalid data type in lookup_options for key '%{key}' could not parse '%{source}', error: '%{msg}") %
              { key: key, source: convert_to[0], msg: e.message }
      end
    end
    begin
      result = lookup_invocation.scope.call_function(NEW, [convert_to[0], result, *convert_to[1..]])
      # TRANSLATORS 'lookup_options', 'convert_to' and args_string variable should not be translated,
      args_string = Puppet::Pops::Types::StringConverter.singleton.convert(convert_to)
      lookup_invocation.report_text { _("Applying convert_to lookup_option with arguments %{args}") % { args: args_string } }
    rescue StandardError => e
      raise Puppet::DataBinding::LookupError,
            _("The convert_to lookup_option for key '%{key}' raised error: %{msg}") %
            { key: key, msg: e.message }
    end
    result
  end

  def lookup_global(key, lookup_invocation, merge_strategy)
    # hiera_xxx will always use global_provider regardless of data_binding_terminus setting
    terminus = lookup_invocation.hiera_xxx_call? ? :hiera : Puppet[:data_binding_terminus]
    case terminus
    when :hiera, 'hiera'
      provider = global_provider(lookup_invocation)
      throw :no_such_key if provider.nil?
      provider.key_lookup(key, lookup_invocation, merge_strategy)
    when :none, 'none', '', nil
      # If global lookup is disabled, immediately report as not found
      lookup_invocation.report_not_found(key)
      throw :no_such_key

View on GitHub (pinned to e227c27540)

Solutions

  1. Fix the source data so the value is convertible (the %{msg} says exactly why new() refused it).
  2. Loosen the target type where the data is legitimately varied (Optional[Integer], Variant[Integer, String]) or normalize data upstream.
  3. For String formatting, use valid format arguments, e.g. convert_to: ['String', '%.2f'] with a numeric value.
  4. Temporarily remove convert_to for that key and inspect the raw looked-up value to find which hierarchy layer supplied the bad data.

Example fix

# before: data/common.yaml
lookup_options:
  myapp::port:
    convert_to: 'Integer'
myapp::port: 'abc'

# after
lookup_options:
  myapp::port:
    convert_to: 'Integer[0, 65535]'
myapp::port: 8080
Defensive patterns

Strategy: validation

Validate before calling

# Smoke-check: found values must survive the configured convert_to
require 'puppet'

value = Puppet::Pops::Lookup.lookup('myapp::port', nil, nil, false, nil, :priority, invocation) rescue nil
convert_to = 'Integer[0, 65535]'
type = Puppet::Pops::Types::TypeParser.singleton.parse(convert_to)
begin
  Puppet::Pops::Types::PObjectType? # noop
  converted = Puppet::Functions.create_function(:noop) # placeholder
rescue StandardError
end
ok = type.instance?(value) rescue false
warn "value #{value.inspect} will fail convert_to #{convert_to}" unless ok || value.nil?

Try / catch

begin
  $port = lookup('myapp::port')   # convert_to applies inside lookup
rescue Puppet::DataBinding::LookupError => e
  raise unless e.message.include?('convert_to lookup_option')
  # fall back: fetch raw and convert leniently
  $port = Integer(lookup('myapp::port_raw', String, '8080'))
end

Prevention

When it happens

Trigger: Data has myapp::port: 'abc' with convert_to 'Integer'; convert_to 'Enum[dev, prod]' but data says 'staging'; convert_to 'Hash[String, Integer]' on an array; extra args like ['String', '%d'] applied to a non-numeric value.

Common situations: Heterogeneous data across hierarchy layers where one layer's value is not convertible; per-node overrides in a different format; regex/format arguments for String conversion that do not match the value.

Related errors


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