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

Unrecognized value for request 'merge' parameter

Error message

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

What it means

The (deprecated) Hiera data-binding terminus converts the lookup 'merge' option into a Hiera resolution type via convert_merge. Accepted values: nil or 'first', a Puppet::Pops::MergeStrategy object, 'unique', 'hash', 'deep', or a Hash whose 'strategy' key is one of those strings. Anything else - true, false as a non-nil boolean true, symbols like :deep, or unknown strings - raises Puppet::DataBinding::LookupError.

Solutions

  1. Pass one of the strings 'first', 'unique', 'hash', 'deep', or nil, as the merge value.
  2. For deep merge options pass a Hash with string keys: { 'strategy' => 'deep', 'merge_hash_arrays' => true }.
  3. Use Puppet::Pops::MergeStrategy objects when integrating with the modern lookup API.
  4. Migrate off this terminus (the class is deprecated): use the lookup() function or Puppet::DataBinding.indirection.terminus(:hiera).

Example fix

# before
Puppet::DataBinding.indirection.find(key, nil,
  variables: scope, merge: :deep)
# LookupError: Unrecognized value for request 'merge' parameter: ':deep'

# after
Puppet::DataBinding.indirection.find(key, nil,
  variables: scope, merge: { 'strategy' => 'deep' })
Defensive patterns

Strategy: type-guard

Validate before calling

raise ArgumentError, 'unsupported merge value' unless valid_merge?(merge)
options = { variables: scope, merge: merge }

Type guard

MERGE_WORDS = %w[first unique hash deep].freeze

def valid_merge?(value)
  value.nil? ||
    (value.is_a?(String) && MERGE_WORDS.include?(value)) ||
    value.is_a?(Puppet::Pops::MergeStrategy) ||
    (value.is_a?(Hash) && (value['strategy'].nil? || MERGE_WORDS.include?(value['strategy'])))
end

Prevention

When it happens

Trigger: Calling the hiera data binding terminus with options[:merge] of an unsupported type: merge: true, merge: :unique, merge: 'array', or a Hash whose 'strategy' is an unrecognized value that recurses into the else branch.

Common situations: Tooling that passes booleans for deep merge (hiera 3 CLI habits); symbolized YAML keys producing Hashes without a usable 'strategy'; code written against the modern lookup() API reused against this terminus.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at lib/puppet/indirector/hiera.rb:74

      # Equivalent to Hiera :hash with default :native merge behavior. A Hash must be passed here
      # to override possible Hiera deep merge config settings.
      { :behavior => :native }
    when 'deep'
      # Equivalent to Hiera :hash with :deeper merge behavior.
      { :behavior => :deeper }
    when Hash
      strategy = merge['strategy']
      if strategy == 'deep'
        result = { :behavior => :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
      # TRANSLATORS "merge" is a parameter name and should not be translated
      raise Puppet::DataBinding::LookupError, _("Unrecognized value for request 'merge' parameter: '%{merge}'") % { merge: merge }
    end
  end

  public

  def self.hiera_config
    hiera_config = Puppet.settings[:hiera_config]
    config = {}

    if Puppet::FileSystem.exist?(hiera_config)
      config = Hiera::Config.load(hiera_config)
    else
      Puppet.warning _("Config file %{hiera_config} not found, using Hiera defaults") % { hiera_config: hiera_config }
    end

    config[:logger] = 'puppet'
    config
  end

View on GitHub (pinned to e227c27540)