{"record":{"id":"a77771326f2e7b29","repo":"puppetlabs/puppet","slug":"resolution-type-strategy-is-illegal-when-acces","errorCode":null,"errorMessage":"Resolution type :#{strategy} is illegal when accessing values using dotted keys. Offending key was '#{key}'","messagePattern":"Resolution type :#(.+?) is illegal when accessing values using dotted keys\\. Offending key was '#(.+?)'","errorType":"exception","errorClass":"Puppet::DataBinding::LookupError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/lookup/global_data_provider.rb","lineNumber":47,"sourceCode":"      unless config.merge_strategy.is_a?(DefaultMergeStrategy)\n        if lookup_invocation.hiera_xxx_call? && merge.is_a?(HashMergeStrategy)\n          # Merge strategy defined in the hiera config only applies when the call stems from a hiera_hash call.\n          merge = config.merge_strategy\n          lookup_invocation.set_hiera_v3_merge_behavior\n        end\n      end\n\n      value = super(key, lookup_invocation, merge)\n      if lookup_invocation.hiera_xxx_call?\n        if merge.is_a?(HashMergeStrategy) || merge.is_a?(DeepMergeStrategy)\n          # hiera_hash calls should error when found values are not hashes\n          Types::TypeAsserter.assert_instance_of('value', Types::PHashType::DEFAULT, value)\n        end\n        if !key.segments.nil? && (merge.is_a?(HashMergeStrategy) || merge.is_a?(UniqueMergeStrategy))\n          strategy = merge.is_a?(HashMergeStrategy) ? 'hash' : 'array'\n\n          # Fail with old familiar message from Hiera 3\n          raise Puppet::DataBinding::LookupError, \"Resolution type :#{strategy} is illegal when accessing values using dotted keys. Offending key was '#{key}'\"\n        end\n      end\n      value\n    else\n      super\n    end\n  end\n\n  protected\n\n  def assert_config_version(config)\n    config.fail(Issues::HIERA_UNSUPPORTED_VERSION_IN_GLOBAL) if config.version == 4\n    config\n  end\n\n  # Return the root of the environment\n  #\n  # @param lookup_invocation [Invocation] The current lookup invocation","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/lookup/global_data_provider.rb#L29-L65","documentation":"This guard lives in the Hiera-3-compatibility shim of the global data provider: it only fires when lookup_invocation.hiera_xxx_call? is true (the legacy hiera()/hiera_hash()/hiera_array() functions), the requested key is a LookupKey with segments (a dotted key like 'app.db.host'), and the merge behavior is HashMergeStrategy (hiera_hash) or UniqueMergeStrategy (hiera_array). Dotted keys require the found value to be traversed per segment, which is incompatible with merging multiple found values, so it reproduces Hiera 3's familiar failure message.","triggerScenarios":"Calling hiera_hash('myapp.settings.override') or hiera_array('my.list.items') — any dotted key — in a manifest or ERB template while data providers are in play; hiera() with an explicit hash/array merge and a dotted key also qualifies via the shim.","commonSituations":"Old Puppet 3-era code still using hiera_hash/hiera_array after moving to Puppet 4+/Hiera 5 data; keys deliberately named with dots (e.g. 'nginx.worker_processes') interacting with legacy function calls.","solutions":["Replace the legacy call with the modern lookup function: lookup('myapp.settings.override', Hash, {'merge' => 'hash'}) — dotted keys work with merge in lookup() because it resolves segments after merging.","Or drop the merge behavior for that key: hiera('my.key.parts') / lookup without hash/array merge.","Or rename the data key to use '::' instead of dots so it is not treated as a segmented (dotted) key."],"exampleFix":"# before\n$d = hiera_hash('myapp.settings.override')\n\n# after\n$d = lookup('myapp.settings.override', Hash, {'merge' => 'hash'})","handlingStrategy":"validation","validationCode":"# Guard a legacy call path: never use hiera_hash/hiera_array with dotted keys\nKEY = 'myapp.settings.override'\nif KEY.include?('.')\n  $value = lookup(KEY, Hash, {'merge' => 'hash'})   # modern lookup handles dotted keys + merge\nelse\n  $value = hiera_hash(KEY)\nend","typeGuard":null,"tryCatchPattern":"begin\n  $value = hiera_hash('myapp.settings.override')\nrescue Puppet::DataBinding::LookupError => e\n  raise unless e.message.include?('illegal when accessing values using dotted keys')\n  $value = lookup('myapp.settings.override', Hash, {'merge' => 'hash'})\nend","preventionTips":["Prefer lookup() over hiera_hash()/hiera_array() in all manifests — the legacy functions have dotted-key limits by design.","Avoid dots in Hiera key names ('myapp::db_host' instead of 'myapp.db.host') to sidestep segment semantics entirely.","Grep codebases for hiera_(hash|array)\\(.*\\. during Puppet 3→4 migrations."],"tags":["puppet","hiera","dotted-keys","hiera-3-compat","merge-conflict"],"backgroundTag":"hiera-dotted-key-merge-conflict","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}