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

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.

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)

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.

Related errors


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