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

Invalid data type in lookup_options for key '%{key}' could n

Error message

Invalid data type in lookup_options for key '%{key}' could not parse '%{source}', error: '%{msg}

What it means

In LookupAdapter#convert_result, when a key has a lookup_options entry with a 'convert_to' option whose first element is a String, that string is parsed by Types::TypeParser to get a Puppet type. If parsing raises (malformed type expression), it is wrapped into Puppet::DataBinding::LookupError 'Invalid data type in lookup_options...' naming the key, the offending source string, and the parser error. This validates the convert_to type string before it is ever used to call the new() function.

Source

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

  #
  # @param key [String] The key to lookup
  # @param lookup_options [Hash] a hash of options
  # @param lookup_invocation [Invocation] the lookup invocation
  # @param the_lookup [Lambda] zero arg lambda that performs the lookup of a value
  # @return [Object] the looked up value, or converted value if there was conversion
  # @throw :no_such_key when the object is not found (if thrown by `the_lookup`)
  #
  def convert_result(key, lookup_options, lookup_invocation, the_lookup)
    result = the_lookup.call
    convert_to = lookup_options[CONVERT_TO]
    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)

View on GitHub (pinned to e227c27540)

Solutions

  1. Fix the type expression in the lookup_options entry to valid Puppet type syntax — the parser message in %{msg} pinpoints the syntax problem.
  2. Validate expressions quickly: `puppet lookup --explain myapp::port` or test the string with TypeParser in a script.
  3. Keep complex types in a type alias (types/mytype.pp) and reference the alias by name in convert_to where supported by your data design.

Example fix

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

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

Strategy: validation

Validate before calling

# Validate every convert_to type string parses before deploy
require 'puppet'
require 'puppet/pops/types/type_parser'

Dir['**/data/**/*.yaml'].each do |f|
  (YAML.load_file(f)['lookup_options'] || {}).each do |key, opts|
    ct = opts.is_a?(Hash) ? opts['convert_to'] : nil
    next unless ct.is_a?(String)
    begin
      Puppet::Pops::Types::TypeParser.singleton.parse(ct)
    rescue StandardError => e
      abort "#{f}: lookup_options[#{key}] convert_to '#{ct}' does not parse: #{e.message}"
    end
  end
end

Prevention

When it happens

Trigger: Data file: `lookup_options: { 'myapp::port': { 'convert_to': 'Integer[' } }` — unterstrained brackets, unknown type name ('Intger'), bad syntax ('Array[String'), or a non-type expression ('8080'). The failure occurs at lookup time of myapp::port, not at config load.

Common situations: Typos in long Struct[...] / Optional[...] type strings; YAML quoting mistakes that mangle brackets; copy-paste from docs leaving placeholders; assuming Ruby type syntax works ('Hash<String,Integer>' must be 'Hash[String, Integer]').

Related errors


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