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_keyView on GitHub (pinned to e227c27540)
Solutions
- Fix the source data so the value is convertible (the %{msg} says exactly why new() refused it).
- Loosen the target type where the data is legitimately varied (Optional[Integer], Variant[Integer, String]) or normalize data upstream.
- For String formatting, use valid format arguments, e.g. convert_to: ['String', '%.2f'] with a numeric value.
- 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
- Keep data formats consistent across hierarchy layers so convert_to always succeeds (audit overrides with `puppet lookup --explain`).
- Prefer widening the type (Optional[Integer], Variant[...]) over strict types when data sources are heterogeneous.
- Test each convert_to key in CI by running a real lookup against representative per-layer values.
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
- Invalid data type in lookup_options for key '%{key}' could n
- value of %{opts} must be a hash
- all %{opts} patterns must match a key starting with module n
- all %{opts} keys must start with module name '%{module_name}
- #{subject} #{what},
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/c9c50bcc2916b8cb.
Report an issue: GitHub.