{"record":{"id":"c360c322b650a182","repo":"puppetlabs/puppet","slug":"unrecognized-value-for-request-merge-parameter-c360c3","errorCode":null,"errorMessage":"Unrecognized value for request 'merge' parameter: '#{merge}'","messagePattern":"Unrecognized value for request 'merge' parameter: '#(.+?)'","errorType":"exception","errorClass":"Puppet::DataBinding::LookupError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/lookup/data_dig_function_provider.rb","lineNumber":141,"sourceCode":"    when 'deep', 'unconstrained_deep'\n      # Equivalent to Hiera :hash with :deeper merge behavior.\n      { :behavior => :deeper }\n    when 'reverse_deep'\n      # Equivalent to Hiera :hash with :deep merge behavior.\n      { :behavior => :deep }\n    when Hash\n      strategy = merge['strategy']\n      case strategy\n      when 'deep', 'unconstrained_deep', 'reverse_deep'\n        result = { :behavior => strategy == 'reverse_deep' ? :deep : :deeper }\n        # Remaining entries must have symbolic keys\n        merge.each_pair { |k, v| result[k.to_sym] = v unless k == 'strategy' }\n        result\n      else\n        convert_merge(strategy)\n      end\n    else\n      raise Puppet::DataBinding::LookupError, \"Unrecognized value for request 'merge' parameter: '#{merge}'\"\n    end\n  end\nend\nend\nend\n","sourceCodeStart":123,"sourceCodeEnd":147,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/lookup/data_dig_function_provider.rb#L123-L147","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","solutions":["Use the supported vocabulary: 'first' (default), 'unique' (was hiera_array), 'hash', 'deep', 'unconstrained_deep', 'reverse_deep'.","For options, pass a Hash: {'strategy' => 'deep', 'merge_hash_arrays' => true, 'knockout_prefix' => '--'} — extra keys are symbolized and forwarded.","Quote the value in YAML and ensure it is a plain String (or Hash), not a symbol/array/number."],"exampleFix":"# before\nlookup('myapp::ports', {'merge' => 'array'})   # 'array' is Hiera 3 vocabulary\n\n# after\nlookup('myapp::ports', {'merge' => 'unique'})\n# or with deep options\nlookup('myapp::config', {'merge' => {'strategy' => 'deep', 'merge_hash_arrays' => true}})","handlingStrategy":"type-guard","validationCode":"# Whitelist merge values before passing them to lookup()\nVALID_MERGE_STRINGS = ['first', 'default', 'unique', 'hash', 'deep', 'unconstrained_deep', 'reverse_deep'].freeze\n\ndef safe_merge(merge)\n  case merge\n  when nil then nil\n  when String\n    VALID_MERGE_STRINGS.include?(merge) ? merge : raise(ArgumentError, \"unsupported merge '#{merge}'\")\n  when Hash\n    merge['strategy'].nil? || VALID_MERGE_STRINGS.include?(merge['strategy']) ? merge : raise(ArgumentError, \"unsupported strategy\")\n  else raise(ArgumentError, 'merge must be a String or Hash')\n  end\nend","typeGuard":"# Ruby guard for the lookup 'merge' option\ndef valid_merge?(m)\n  return true if m.nil?\n  return true if m.is_a?(String) && %w[first default unique hash deep unconstrained_deep reverse_deep].include?(m)\n  return true if m.is_a?(Hash) && (m['strategy'].nil? || m['strategy'].is_a?(String))\n  false\nend","tryCatchPattern":"begin\n  lookup('myapp::config', {'merge' => user_merge})\nrescue Puppet::DataBinding::LookupError => e\n  raise unless e.message.include?(\"Unrecognized value for request 'merge'\")\n  lookup('myapp::config')  # retry with default (first) merge\nend","preventionTips":["Memorize the Hiera 5 vocabulary: first/unique/hash/deep/unconstrained_deep/reverse_deep — not :array/:priority.","When accepting merge settings from users/config, validate against the whitelist before calling lookup().","In YAML, quote merge values so they stay strings, and pass options as a Hash with a 'strategy' key."],"tags":["puppet","hiera","lookup","merge-strategy","invalid-argument"],"backgroundTag":"hiera-invalid-merge-strategy","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}