puppetlabs/puppet · error · ArgumentError
Functions must be based on Puppet::Pops::Functions::Function
Error message
Functions must be based on Puppet::Pops::Functions::Function. Got %{function_base} What it means
create_loaded_function validates that the base class passed as function_base has Puppet::Pops::Functions::Function among its ancestors. Any class that skips that chain, or a Module passed instead of a Class, raises this ArgumentError at definition time. The base class is the second argument to Puppet::Functions.create_function.
Source
Thrown at lib/puppet/functions.rb:213
raise ArgumentError, _("Function Load Error for function '%{function_name}': %{message}") % { function_name: func_name, message: e.message }
end
# Creates a function in, or in a local loader under the given loader.
# This method should only be used when manually creating functions
# for the sake of testing. Functions that are autoloaded should
# always use the `create_function` method and the autoloader will supply
# the correct loader.
#
# @param func_name [String, Symbol] a simple or qualified function name
# @param loader [Puppet::Pops::Loaders::Loader] the loader loading the function
# @param block [Proc] the block that defines the methods and dispatch of the
# Function to create
# @return [Class<Function>] the newly created Function class
#
# @api public
def self.create_loaded_function(func_name, loader, function_base = Function, &block)
if function_base.ancestors.none? { |s| s == Puppet::Pops::Functions::Function }
raise ArgumentError, _("Functions must be based on Puppet::Pops::Functions::Function. Got %{function_base}") % { function_base: function_base }
end
func_name = func_name.to_s
# Creates an anonymous class to represent the function
# The idea being that it is garbage collected when there are no more
# references to it.
#
# (Do not give the class the block here, as instance variables should be set first)
the_class = Class.new(function_base)
unless loader.nil?
the_class.instance_variable_set(:'@loader', loader.private_loader)
end
# Make the anonymous class appear to have the class-name <func_name>
# Even if this class is not bound to such a symbol in a global ruby scope and
# must be resolved via the loader.
# This also overrides any attempt to define a name method in the given blockView on GitHub (pinned to e227c27540)
Solutions
- Derive the custom base from Puppet::Functions::Function so the ancestor check passes.
- If you only need shared helpers, drop the custom base and include ordinary Ruby modules inside the create_function block instead.
- Confirm you passed a Class, not a Module, as the second argument.
Example fix
# before: base class outside the Function hierarchy
class MyCoolBase; end
Puppet::Functions.create_function(:f, MyCoolBase) { ... }
# after: derive from Puppet::Functions::Function
class MyCoolBase < Puppet::Functions::Function; end
Puppet::Functions.create_function(:f, MyCoolBase) { ... } Defensive patterns
Strategy: type-guard
Type guard
# Guard the base class before calling create_function def valid_function_base?(klass) klass.is_a?(Class) && klass.ancestors.include?(Puppet::Pops::Functions::Function) end raise ArgumentError, 'bad base' unless valid_function_base?(MyCoolBase)
Prevention
- Derive custom bases from Puppet::Functions::Function by habit.
- Prefer mixins included inside the block over custom base classes.
- Assert ancestors in the spec for any shared function base.
When it happens
Trigger: Puppet::Functions.create_function(:foo, MyCustomBase) where MyCustomBase does not derive from Puppet::Functions::Function (which itself derives from Puppet::Pops::Functions::Function). Also triggered by passing a Module used as a mixin, or a typo'd constant that resolves to an unrelated class.
Common situations: Authors adding shared behavior through a custom function base; refactors that reparent the base class; scaffolding copied between Puppet versions where the base hierarchy changed.
Related errors
- Function Load Error for function '%{function_name}': %{messa
- Function Creation Error, cannot create a default dispatcher
- A required parameter cannot be added after an optional param
- A required repeated parameter cannot be added after an optio
- block_param accepts max 2 arguments (type, name), got %{size
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/e246edf85dfbae78.
Report an issue: GitHub.