puppetlabs/puppet · error · ArgumentError
Attempt to redefine block
Error message
Attempt to redefine block
What it means
A dispatch signature may declare at most one block parameter. The first block_param (or optional_block_param, which delegates to it) sets @block_type; any second call finds @block_type non-nil and raises this ArgumentError.
Source
Thrown at lib/puppet/functions.rb:503
type, name = type_and_name
type = Puppet::Pops::Types::TypeParser.singleton.parse(type, loader) unless type.is_a?(Puppet::Pops::Types::PAnyType)
else
raise ArgumentError, _("block_param accepts max 2 arguments (type, name), got %{size}.") % { size: type_and_name.size }
end
unless Puppet::Pops::Types::TypeCalculator.is_kind_of_callable?(type, false)
raise ArgumentError, _("Expected PCallableType or PVariantType thereof, got %{type_class}") % { type_class: type.class }
end
unless name.is_a?(Symbol)
raise ArgumentError, _("Expected block_param name to be a Symbol, got %{name_class}") % { name_class: name.class }
end
if @block_type.nil?
@block_type = type
@block_name = name
else
raise ArgumentError, _('Attempt to redefine block')
end
end
alias required_block_param block_param
# Defines one optional block parameter that may appear last. If type or name is missing the
# defaults are "any callable", and the name is "block". The implementor of the dispatch target
# must use block = nil when it is optional (or an error is raised when the call is made).
#
# @api public
def optional_block_param(*type_and_name)
# same as required, only wrap the result in an optional type
required_block_param(*type_and_name)
@block_type = Puppet::Pops::Types::TypeFactory.optional(@block_type)
end
# Defines the return type. Defaults to 'Any'
# @param [String] type a reference to a Puppet Data Type
#View on GitHub (pinned to e227c27540)
Solutions
- Keep exactly one block_param or optional_block_param per dispatch block.
- If two callbacks are needed, pass the second as a regular param typed 'Callable[...]' and call it with the call() function or a lambda.
- Split the signature into two dispatch blocks if the two blocks belong to different call shapes.
Example fix
# before: two block parameters in one dispatch dispatch :m do param 'String', :s block_param 'Callable', :block optional_block_param 'Callable', :on_error # raises: redefine end # after: one block, second callback is a Callable param dispatch :m do param 'String', :s param 'Callable', :on_error block_param 'Callable', :block end
Defensive patterns
Strategy: validation
Validate before calling
# CI grep: more than one block-param declaration inside a single dispatch block ! grep -Pzo 'dispatch[^}]*block_param[^}]*\n[^}]*(block_param|optional_block_param)' lib/puppet/functions/**/*.rb
Prevention
- Allow exactly one block_param or optional_block_param per dispatch block.
- Pass extra callbacks as 'Callable' params, invoked with call().
- Never copy a block_param line when adding parameters.
When it happens
Trigger: block_param 'Callable', :block followed later in the same dispatch block by optional_block_param 'Callable', :fallback, or by a second block_param with a different name.
Common situations: Trying to accept two different blocks (a transformer and an error handler) in one signature; copy-paste of an existing block_param line when adding a new parameter.
Related errors
- block_param accepts max 2 arguments (type, name), got %{size
- Function Load Error for function '%{function_name}': %{messa
- A required parameter cannot be added after an optional param
- Expected PCallableType or PVariantType thereof, got %{type_c
- Expected block_param name to be a Symbol, got %{name_class}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/653ccc1e9ff9e09d.
Report an issue: GitHub.