puppetlabs/puppet · error · ArgumentError
The code loaded from %{source_ref} produced mis-matched name
Error message
The code loaded from %{source_ref} produced mis-matched name, expected '%{type_name}', got %{created_name} What it means
Raised by RubyFunctionInstantiator when the class produced by eval has a name different from the typed name. The symbol passed to Puppet::Functions.create_function must exactly match (case-sensitive == on to_s) the function name the loader binds, which is derived from the module layout and file path (e.g. mymod::double in lib/puppet/functions/mymod/double.rb).
Source
Thrown at lib/puppet/pops/loader/ruby_function_instantiator.rb:30
# @param source_ref [URI, String] a reference to the source / origin of the ruby code to evaluate
# @param ruby_code_string [String] ruby code in a string
#
# @return [Puppet::Pops::Functions.Function] - an instantiated function with global scope closure associated with the given loader
#
def self.create(loader, typed_name, source_ref, ruby_code_string)
unless ruby_code_string.is_a?(String) && ruby_code_string =~ /Puppet::Functions\.create_function/
raise ArgumentError, _("The code loaded from %{source_ref} does not seem to be a Puppet 4x API function - no create_function call.") % { source_ref: source_ref }
end
# make the private loader available in a binding to allow it to be passed on
loader_for_function = loader.private_loader
here = get_binding(loader_for_function)
created = eval(ruby_code_string, here, source_ref, 1) # rubocop:disable Security/Eval
unless created.is_a?(Class)
raise ArgumentError, _("The code loaded from %{source_ref} did not produce a Function class when evaluated. Got '%{klass}'") % { source_ref: source_ref, klass: created.class }
end
unless created.name.to_s == typed_name.name()
raise ArgumentError, _("The code loaded from %{source_ref} produced mis-matched name, expected '%{type_name}', got %{created_name}") % { source_ref: source_ref, type_name: typed_name.name, created_name: created.name }
end
# create the function instance - it needs closure (scope), and loader (i.e. where it should start searching for things
# when calling functions etc.
# It should be bound to global scope
# Sets closure scope to nil, to let it be picked up at runtime from Puppet.lookup(:global_scope)
# If function definition used the loader from the binding to create a new loader, that loader wins
created.new(nil, loader_for_function)
end
# Produces a binding where the given loader is bound as a local variable (loader_injected_arg). This variable can be used in loaded
# ruby code - e.g. to call Puppet::Function.create_loaded_function(:name, loader,...)
#
def self.get_binding(loader_injected_arg)
binding
end
private_class_method :get_bindingView on GitHub (pinned to e227c27540)
Solutions
- Match the create_function symbol exactly to the namespaced name derived from the file path
- Rename the file or the symbol so both agree
- Remember this check is case-sensitive, unlike the data-type instantiator's casecmp
Example fix
# before - lib/puppet/functions/mymod/double.rb Puppet::Functions.create_function(:'mymod::twice') do ... end # after Puppet::Functions.create_function(:'mymod::double') do ... end
Defensive patterns
Strategy: try-catch
Validate before calling
m = ruby_source.match(/Puppet::Functions\.create_function\(\s*:?'([^']+)'|Puppet::Functions\.create_function\(\s*:?"([^"]+)"/)
expected = namespaced_name_from_path(path)
warn "name mismatch: file says #{m && (m[1] || m[2])}, path says #{expected}" if m && (m[1] || m[2]) != expected Try / catch
begin
fn = loader.load_typed(typed_name)
rescue ArgumentError => e
raise unless e.message.include?('mis-matched name')
warn "function name mismatch: #{e.message}"
end Prevention
- Namespace 4x function symbols as 'module::name' matching the file path
- Rename file and symbol together
- Watch case: this comparison is case-sensitive
When it happens
Trigger: `created.name.to_s != typed_name.name`: e.g. create_function(:'mymod::foo') in a file loaded as mymod::bar, or a missing module namespace segment (defining :double where :mymod::double is expected).
Common situations: Renaming a function in code but not the file (or vice versa); omitting the module namespace during 3x-to-4x migration; copy-pasted functions with stale names.
Related errors
- The code loaded from %{source_ref} produced mis-matched name
- The code loaded from %{source_ref} does not seem to be a Pup
- The code loaded from %{source_ref} did not produce a Functio
- The code loaded from %{source_ref} produced mis-matched name
- The code loaded from %{source} contains additional logic - c
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/54fa8f829a5941d6.
Report an issue: GitHub.