{"record":{"id":"c9c50bcc2916b8cb","repo":"puppetlabs/puppet","slug":"the-convert-to-lookup-option-for-key-key-rais","errorCode":null,"errorMessage":"The convert_to lookup_option for key '%{key}' raised error: %{msg}","messagePattern":"The convert_to lookup_option for key '%(.+?)' raised error: %(.+?)","errorType":"exception","errorClass":"Puppet::DataBinding::LookupError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/lookup/lookup_adapter.rb","lineNumber":119,"sourceCode":"    return result if convert_to.nil?\n\n    convert_to = convert_to.is_a?(Array) ? convert_to : [convert_to]\n    if convert_to[0].is_a?(String)\n      begin\n        convert_to[0] = Puppet::Pops::Types::TypeParser.singleton.parse(convert_to[0])\n      rescue StandardError => e\n        raise Puppet::DataBinding::LookupError,\n              _(\"Invalid data type in lookup_options for key '%{key}' could not parse '%{source}', error: '%{msg}\") %\n              { key: key, source: convert_to[0], msg: e.message }\n      end\n    end\n    begin\n      result = lookup_invocation.scope.call_function(NEW, [convert_to[0], result, *convert_to[1..]])\n      # TRANSLATORS 'lookup_options', 'convert_to' and args_string variable should not be translated,\n      args_string = Puppet::Pops::Types::StringConverter.singleton.convert(convert_to)\n      lookup_invocation.report_text { _(\"Applying convert_to lookup_option with arguments %{args}\") % { args: args_string } }\n    rescue StandardError => e\n      raise Puppet::DataBinding::LookupError,\n            _(\"The convert_to lookup_option for key '%{key}' raised error: %{msg}\") %\n            { key: key, msg: e.message }\n    end\n    result\n  end\n\n  def lookup_global(key, lookup_invocation, merge_strategy)\n    # hiera_xxx will always use global_provider regardless of data_binding_terminus setting\n    terminus = lookup_invocation.hiera_xxx_call? ? :hiera : Puppet[:data_binding_terminus]\n    case terminus\n    when :hiera, 'hiera'\n      provider = global_provider(lookup_invocation)\n      throw :no_such_key if provider.nil?\n      provider.key_lookup(key, lookup_invocation, merge_strategy)\n    when :none, 'none', '', nil\n      # If global lookup is disabled, immediately report as not found\n      lookup_invocation.report_not_found(key)\n      throw :no_such_key","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/lookup/lookup_adapter.rb#L101-L137","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: data/common.yaml\nlookup_options:\n  myapp::port:\n    convert_to: 'Integer'\nmyapp::port: 'abc'\n\n# after\nlookup_options:\n  myapp::port:\n    convert_to: 'Integer[0, 65535]'\nmyapp::port: 8080","handlingStrategy":"validation","validationCode":"# Smoke-check: found values must survive the configured convert_to\nrequire 'puppet'\n\nvalue = Puppet::Pops::Lookup.lookup('myapp::port', nil, nil, false, nil, :priority, invocation) rescue nil\nconvert_to = 'Integer[0, 65535]'\ntype = Puppet::Pops::Types::TypeParser.singleton.parse(convert_to)\nbegin\n  Puppet::Pops::Types::PObjectType? # noop\n  converted = Puppet::Functions.create_function(:noop) # placeholder\nrescue StandardError\nend\nok = type.instance?(value) rescue false\nwarn \"value #{value.inspect} will fail convert_to #{convert_to}\" unless ok || value.nil?","typeGuard":null,"tryCatchPattern":"begin\n  $port = lookup('myapp::port')   # convert_to applies inside lookup\nrescue Puppet::DataBinding::LookupError => e\n  raise unless e.message.include?('convert_to lookup_option')\n  # fall back: fetch raw and convert leniently\n  $port = Integer(lookup('myapp::port_raw', String, '8080'))\nend","preventionTips":["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."],"tags":["puppet","hiera","lookup-options","convert-to","type-mismatch"],"backgroundTag":"hiera-convert-to-failure","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}