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

Unrecognized value for request 'merge' parameter: '#{merge}'

Error message

Unrecognized value for request 'merge' parameter: '#{merge}'

What it means

DataDigFunctionProvider.convert_merge translates the lookup() 'merge' argument into a Hiera resolution type. It accepts nil/'first'/'default', the strings 'unique', 'hash', 'deep', 'unconstrained_deep', 'reverse_deep', a Puppet::Pops::MergeStrategy, or a Hash with a 'strategy' key (whose value must recursively convert). Anything else — Integer, Array, symbol, or an unrecognized string like 'array', 'priority', or 'native' — falls to the else branch and raises Puppet::DataBinding::LookupError.

Source

Thrown at lib/puppet/pops/lookup/data_dig_function_provider.rb:141

    when 'deep', 'unconstrained_deep'
      # Equivalent to Hiera :hash with :deeper merge behavior.
      { :behavior => :deeper }
    when 'reverse_deep'
      # Equivalent to Hiera :hash with :deep merge behavior.
      { :behavior => :deep }
    when Hash
      strategy = merge['strategy']
      case strategy
      when 'deep', 'unconstrained_deep', 'reverse_deep'
        result = { :behavior => strategy == 'reverse_deep' ? :deep : :deeper }
        # Remaining entries must have symbolic keys
        merge.each_pair { |k, v| result[k.to_sym] = v unless k == 'strategy' }
        result
      else
        convert_merge(strategy)
      end
    else
      raise Puppet::DataBinding::LookupError, "Unrecognized value for request 'merge' parameter: '#{merge}'"
    end
  end
end
end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Use the supported vocabulary: 'first' (default), 'unique' (was hiera_array), 'hash', 'deep', 'unconstrained_deep', 'reverse_deep'.
  2. For options, pass a Hash: {'strategy' => 'deep', 'merge_hash_arrays' => true, 'knockout_prefix' => '--'} — extra keys are symbolized and forwarded.
  3. Quote the value in YAML and ensure it is a plain String (or Hash), not a symbol/array/number.

Example fix

# before
lookup('myapp::ports', {'merge' => 'array'})   # 'array' is Hiera 3 vocabulary

# after
lookup('myapp::ports', {'merge' => 'unique'})
# or with deep options
lookup('myapp::config', {'merge' => {'strategy' => 'deep', 'merge_hash_arrays' => true}})
Defensive patterns

Strategy: type-guard

Validate before calling

# Whitelist merge values before passing them to lookup()
VALID_MERGE_STRINGS = ['first', 'default', 'unique', 'hash', 'deep', 'unconstrained_deep', 'reverse_deep'].freeze

def safe_merge(merge)
  case merge
  when nil then nil
  when String
    VALID_MERGE_STRINGS.include?(merge) ? merge : raise(ArgumentError, "unsupported merge '#{merge}'")
  when Hash
    merge['strategy'].nil? || VALID_MERGE_STRINGS.include?(merge['strategy']) ? merge : raise(ArgumentError, "unsupported strategy")
  else raise(ArgumentError, 'merge must be a String or Hash')
  end
end

Type guard

# Ruby guard for the lookup 'merge' option
def valid_merge?(m)
  return true if m.nil?
  return true if m.is_a?(String) && %w[first default unique hash deep unconstrained_deep reverse_deep].include?(m)
  return true if m.is_a?(Hash) && (m['strategy'].nil? || m['strategy'].is_a?(String))
  false
end

Try / catch

begin
  lookup('myapp::config', {'merge' => user_merge})
rescue Puppet::DataBinding::LookupError => e
  raise unless e.message.include?("Unrecognized value for request 'merge'")
  lookup('myapp::config')  # retry with default (first) merge
end

Prevention

When it happens

Trigger: lookup({'name' => 'k', 'merge' => 'array'}) (Hiera 3 vocabulary); merge => :deep as a symbol; merge => ['deep','hash'] as an array; merge => {'strategy' => 'shallow'} where the inner string is unknown; data_dig-based providers converting the same option set.

Common situations: Migrating Hiera 3 hiera_array/hiera_hash calls to lookup() and passing the old :array/:priority symbols or strings; YAML data where merge: is parsed as a symbol or list; typos like 'deep_merge' or 'knockout'.

Related errors


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