puppetlabs/puppet · error · Puppet::DataBinding::LookupError
all %{opts} patterns must match a key starting with module n
Error message
all %{opts} patterns must match a key starting with module name '%{module_name}' What it means
When lookup_options comes from module data, validate_lookup_options enforces module scoping: keys starting with '^' (LOOKUP_OPTIONS_PATTERN_START) are regex patterns, and the text right after the caret must equal '<module_name>::' (key[1..pfx.length] == pfx). A module may only define lookup_options patterns matching its own keys; a broader pattern raises Puppet::DataBinding::LookupError.
Source
Thrown at lib/puppet/pops/lookup/lookup_adapter.rb:307
def set_global_only
@global_only = true
self
end
private
PROVIDER_STACK = [:lookup_global, :lookup_in_environment, :lookup_in_module].freeze
def validate_lookup_options(options, module_name)
return nil if options.nil?
raise Puppet::DataBinding::LookupError, _("value of %{opts} must be a hash") % { opts: LOOKUP_OPTIONS } unless options.is_a?(Hash)
return options if module_name.nil?
pfx = "#{module_name}::"
options.each_pair do |key, _value|
if key.start_with?(LOOKUP_OPTIONS_PATTERN_START)
unless key[1..pfx.length] == pfx
raise Puppet::DataBinding::LookupError, _("all %{opts} patterns must match a key starting with module name '%{module_name}'") % { opts: LOOKUP_OPTIONS, module_name: module_name }
end
else
unless key.start_with?(pfx)
raise Puppet::DataBinding::LookupError, _("all %{opts} keys must start with module name '%{module_name}'") % { opts: LOOKUP_OPTIONS, module_name: module_name }
end
end
end
end
def compile_patterns(options)
return nil if options.nil?
key_options = {}
pattern_options = {}
options.each_pair do |key, value|
if key.start_with?(LOOKUP_OPTIONS_PATTERN_START)
pattern_options[Regexp.compile(key)] = value
elseView on GitHub (pinned to e227c27540)
Solutions
- Scope every '^' pattern in module data to your own module: '^mymodule::.*'.
- Put cross-module or catch-all patterns in environment-level data instead, where module scoping does not apply.
- Remember plain (non-pattern) keys are checked separately — they must also start with 'mymodule::'.
Example fix
# before: modules/mymodule/data/common.yaml
lookup_options:
'^.*':
merge: deep
# after
lookup_options:
'^mymodule::.*':
merge: deep Defensive patterns
Strategy: validation
Validate before calling
# CI check: '^' patterns in module data must match the module's own namespace
require 'yaml'
Dir['modules/*/data/**/*.yaml'].each do |f|
mod = f.split('/')[1]
(YAML.load_file(f)['lookup_options'] || {}).each_key do |key|
next unless key.start_with?('^')
abort "#{f}: pattern '#{key}' must start with '^#{mod}::'" unless key[1..("#{mod}::".length)] == "#{mod}::"
end
end Prevention
- In module data, always write patterns as '^<modulename>::...'.
- Reserve catch-all ('^.*') and cross-module patterns for environment-level data.
- Test module data loading with `puppet lookup --module <name>` style checks in CI.
When it happens
Trigger: In a module's own data (e.g. modules/mymodule/data/common.yaml): `lookup_options: { '^myothermodule::.*': { ... } }` or a generic `'^.*'` — any pattern whose post-caret text is not 'mymodule::'.
Common situations: Module authors trying to set merge behavior for all keys or for other modules' keys from module data; copying environment-level lookup_options verbatim into a module.
Related errors
- all %{opts} keys must start with module name '%{module_name}
- Invalid data type in lookup_options for key '%{key}' could n
- The convert_to lookup_option for key '%{key}' raised error:
- value of %{opts} must be a hash
- Undefined variable '%{name}'; %{reason}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/e69d1766161972d7.
Report an issue: GitHub.