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 'function_%{type_name}', got '%{created_name}'

What it means

Raised by RubyLegacyFunctionInstantiator when the loaded function's info Hash reports a different function name than expected. The check compares func_info[:name] (set by newfunction) against "function_#{typed_name.name}", so the symbol passed to newfunction must match the file name: double.rb must call newfunction(:double, ...).

Source

Thrown at lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb:51

    # Avoid reloading the function if already loaded via one of the APIs that trigger 3x function loading
    # Check if function is already loaded the 3x way (and obviously not the 4x way since we would not be here in the
    # first place.
    environment = Puppet.lookup(:current_environment)
    func_info = Puppet::Parser::Functions.environment_module(environment).get_function_info(typed_name.name.to_sym)
    if func_info.nil?
      # This will do the 3x loading and define the "function_<name>" and "real_function_<name>" methods
      # in the anonymous module used to hold function definitions.
      #
      func_info = eval(ruby_code_string, here, source_ref, 1) # rubocop:disable Security/Eval

      # Validate what was loaded
      unless func_info.is_a?(Hash)
        # TRANSLATORS - the word 'newfunction' should not be translated as it is a method name.
        raise ArgumentError, _("Illegal legacy function definition! The code loaded from %{source_ref} did not return the result of calling 'newfunction'. Got '%{klass}'") % { source_ref: source_ref, klass: func_info.class }
      end

      unless func_info[:name] == "function_#{typed_name.name()}"
        raise ArgumentError, _("The code loaded from %{source_ref} produced mis-matched name, expected 'function_%{type_name}', got '%{created_name}'") % {
          source_ref: source_ref, type_name: typed_name.name, created_name: func_info[:name]
        }
      end
    end

    created = Puppet::Functions::Function3x.create_function(typed_name.name(), func_info, loader_for_function)

    # 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,...)

View on GitHub (pinned to e227c27540)

Solutions

  1. Make the newfunction symbol match the file name exactly
  2. Rename the file to match the symbol if the symbol is the desired name
  3. Re-check after any rename so file name and symbol stay in sync

Example fix

# before - lib/puppet/parser/functions/bar.rb
module Puppet::Parser::Functions
  newfunction(:baz, :type => :rvalue) { |a| a[0] }
end

# after - lib/puppet/parser/functions/bar.rb
module Puppet::Parser::Functions
  newfunction(:bar, :type => :rvalue) { |a| a[0] }
end
Defensive patterns

Strategy: try-catch

Try / catch

begin
  fn = loader.load_typed(typed_name)
rescue ArgumentError => e
  raise unless e.message.include?("expected 'function_")
  warn "legacy function name mismatch: #{e.message}"
end

Prevention

When it happens

Trigger: File bar.rb calls newfunction(:baz, ...): the returned Hash's :name is 'function_baz' while the loader expects 'function_bar' (typed name derived from the file name).

Common situations: Renaming a legacy function file without updating the newfunction symbol; copy-pasted function files; case differences in the symbol.

Related errors


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