{"record":{"id":"f9c6b9d50e343f61","repo":"puppetlabs/puppet","slug":"function-load-error-for-function-function-name","errorCode":null,"errorMessage":"Function Load Error for function '%{function_name}': %{message}","messagePattern":"Function Load Error for function '%(.+?)': %(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/functions.rb","lineNumber":195,"sourceCode":"#\n# @api public\nmodule Puppet::Functions\n  # @param func_name [String, Symbol] a simple or qualified function name\n  # @param block [Proc] the block that defines the methods and dispatch of the\n  #   Function to create\n  # @return [Class<Function>] the newly created Function class\n  #\n  # @api public\n  def self.create_function(func_name, function_base = Function, &block)\n    # Ruby < 2.1.0 does not have method on Binding, can only do eval\n    # and it will fail unless protected with an if defined? if the local\n    # variable does not exist in the block's binder.\n    #\n\n    loader = block.binding.eval('loader_injected_arg if defined?(loader_injected_arg)')\n    create_loaded_function(func_name, loader, function_base, &block)\n  rescue StandardError => e\n    raise ArgumentError, _(\"Function Load Error for function '%{function_name}': %{message}\") % { function_name: func_name, message: e.message }\n  end\n\n  # Creates a function in, or in a local loader under the given loader.\n  # This method should only be used when manually creating functions\n  # for the sake of testing. Functions that are autoloaded should\n  # always use the `create_function` method and the autoloader will supply\n  # the correct loader.\n  #\n  # @param func_name [String, Symbol] a simple or qualified function name\n  # @param loader [Puppet::Pops::Loaders::Loader] the loader loading the function\n  # @param block [Proc] the block that defines the methods and dispatch of the\n  #   Function to create\n  # @return [Class<Function>] the newly created Function class\n  #\n  # @api public\n  def self.create_loaded_function(func_name, loader, function_base = Function, &block)\n    if function_base.ancestors.none? { |s| s == Puppet::Pops::Functions::Function }\n      raise ArgumentError, _(\"Functions must be based on Puppet::Pops::Functions::Function. Got %{function_base}\") % { function_base: function_base }","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/functions.rb#L177-L213","documentation":"Puppet raises this ArgumentError while it creates a Ruby function from a Puppet::Functions.create_function block. Any StandardError raised during creation (a bad dispatch DSL call, an unparseable type string, a Ruby name error inside the block) is caught and re-raised with this wrapper text, and the original message is embedded. This is a definition-time error in the function's own Ruby file, not a call-time error.","triggerScenarios":"The autoloader loads a file under lib/puppet/functions/ whose create_function block fails. Examples: param 'Array[String', :xs (unbalanced type string, surfaces as the nested 'Parsing of type string' error); a reference to a constant that does not exist; use of dispatcher DSL that the running Puppet version does not support.","commonSituations":"Custom functions written against a newer Puppet running on an older one; typos inside dispatch blocks; refactoring that renames a helper the block used; vendored function files with syntax errors that only load when the function is first called.","solutions":["Read the embedded %{message}. It names the real failure; fix that in the function file shown in the backtrace.","Reproduce with a minimal call (puppet apply -e 'notice(my_func())') or by loading the file in a ruby -Ilib session, so you see the full original backtrace.","If the message points at dispatcher or type DSL, check the function against stock functions shipped in your Puppet version; the DSL may be newer than your Puppet.","For third-party modules, pin a module release whose metadata.json supports your Puppet version, or upgrade Puppet."],"exampleFix":"# before: nested parse error -> Function Load Error for function 'bad'\nPuppet::Functions.create_function(:bad) do\n  dispatch :bad do\n    param 'Array[String', :xs   # unbalanced bracket\n  end\n  def bad(xs); xs; end\nend\n\n# after: valid type string, function loads cleanly\nPuppet::Functions.create_function(:bad) do\n  dispatch :bad do\n    param 'Array[String]', :xs\n  end\n  def bad(xs); xs; end\nend","handlingStrategy":"try-catch","validationCode":"# CI: force-load every function file so definition-time errors surface before deploy\nDir['site/*/lib/puppet/functions/**/*.rb'].sort.each { |f| load(f) }","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Pops::Loaders.find_loader(nil).load(:function, 'my_func')\nrescue ArgumentError => e\n  raise unless e.message =~ /Function Load Error/\n  # Deterministic authoring bug: fail fast, surface the embedded %{message}\n  raise \"broken function definition: #{e.message}\" \nend","preventionTips":["Unit-test custom functions with rspec-puppet on the exact deployed Puppet version.","Load all function files in CI so create_function errors never reach a production compile.","Pin module versions whose metadata.json declares support for your Puppet release.","Treat any edit inside a create_function block as needing a compile smoke test."],"tags":["puppet","functions","create-function","load-error","dsl"],"backgroundTag":"function-load-error","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}