puppetlabs/puppet · error · ArgumentError
Expected PCallableType or PVariantType thereof, got %{type_c
Error message
Expected PCallableType or PVariantType thereof, got %{type_class} What it means
The type given to block_param must be callable: a PCallableType or a PVariantType of callables, checked with TypeCalculator.is_kind_of_callable?. A parsed String such as 'String' produces PStringType, which is not callable, so the definition fails with this ArgumentError.
Source
Thrown at lib/puppet/functions.rb:492
#
# @api public
def block_param(*type_and_name)
case type_and_name.size
when 0
type = @all_callables
name = :block
when 1
type = @all_callables
name = type_and_name[0]
when 2
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).View on GitHub (pinned to e227c27540)
Solutions
- Describe the block's signature as a Callable, for example block_param 'Callable[Integer, Integer]', :block.
- If any callable is acceptable, call block_param with no type at all.
- For a block that may be absent, keep the Callable type and use optional_block_param so it is wrapped Optional.
Example fix
# before: String is not a callable type block_param 'String', :block # after: describe the signature the block must have block_param 'Callable[Integer, Integer]', :block # or accept any callable: block_param
Defensive patterns
Strategy: type-guard
Validate before calling
# Pre-parse and check the type exactly as the DSL will
t = Puppet::Pops::Types::TypeParser.singleton.parse('Callable[Integer, Integer]')
raise 'not a callable type' unless Puppet::Pops::Types::TypeCalculator.is_kind_of_callable?(t, false) Type guard
callable_block_type = ->(type_string) {
t = type_string.is_a?(Puppet::Pops::Types::PAnyType) ? type_string :
Puppet::Pops::Types::TypeParser.singleton.parse(type_string)
Puppet::Pops::Types::TypeCalculator.is_kind_of_callable?(t, false)
}
raise ArgumentError, 'bad block type' unless callable_block_type.call('Callable[0,0]') Prevention
- Describe blocks with Callable[...] signatures, never with content types like 'String'.
- When unsure, omit the type: bare block_param accepts any callable.
- Pre-parse new Callable strings in a console before committing.
When it happens
Trigger: block_param 'String', :block, or block_param('Array', :block): the type string parses fine but does not describe a callable. Also triggered by passing a PAnyType subclass instance that is not callable.
Common situations: Authors assuming block_param takes the block's content type (for example 'String' for a block that yields strings) instead of the callable signature type.
Related errors
- Expected block_param name to be a Symbol, got %{name_class}
- block_param accepts max 2 arguments (type, name), got %{size
- Attempt to redefine block
- Argument to 'return_type' must be a String reference to a Pu
- Parameter name argument must be a Symbol. Got %{name_class}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/d79d778fa582b934.
Report an issue: GitHub.