puppetlabs/puppet · error · ArgumentError
Callable tuple may not have a size constraint when used as a
Error message
Callable tuple may not have a size constraint when used as args
What it means
PTupleType#callable_args? answers whether this tuple can be spread as the argument list of a Callable type. A tuple carrying a size_type (Tuple[String, Integer, 1, 3]) denotes a variable number of elements, which cannot be matched element-wise against a signature, so the method raises ArgumentError instead of guessing. It is a private API of the pops type checker; users normally hit it only indirectly, when a Callable is combined with sized tuple/array types in aliases or in Ruby-side signature checks.
Source
Thrown at lib/puppet/pops/types/types.rb:2181
end
# If set, describes min and max required of the given types - if max > size of
# types, the last type entry repeats
#
attr_reader :size_type
attr_reader :types
def accept(visitor, guard)
super
@size_type.accept(visitor, guard) unless @size_type.nil?
@types.each { |elem| elem.accept(visitor, guard) }
end
# @api private
def callable_args?(callable_t, guard)
unless size_type.nil?
raise ArgumentError, 'Callable tuple may not have a size constraint when used as args'
end
params_tuple = callable_t.param_types
param_block_t = callable_t.block_type
arg_types = @types
arg_block_t = arg_types.last
if arg_block_t.kind_of_callable?(true, guard)
# Can't pass a block to a callable that doesn't accept one
return false if param_block_t.nil?
# Check that the block is of the right tyṕe
return false unless param_block_t.assignable?(arg_block_t, guard)
# Check other arguments
arg_count = arg_types.size - 1
params_size_t = params_tuple.size_type || PIntegerType.new(*params_tuple.size_range)
return false unless params_size_t.assignable?(PIntegerType.new(arg_count, arg_count), guard)
View on GitHub (pinned to e227c27540)
Solutions
- Remove the size constraint from the tuple used on the argument side: Tuple[String, Integer] instead of Tuple[String, Integer, 1, 3].
- Declare the callable's parameters explicitly (Callable[String, Integer, 2]) instead of one sized tuple type.
- In Ruby, rebuild the tuple without its size type before checking: PTupleType.new(tuple.types).
- If it reproduces from plain Puppet DSL with no Ruby API use, minimize the case and report it upstream as a type-system bug.
Example fix
# before (type alias) type MyCallback = Callable[Tuple[String, 1, 2]] # sized tuple as args -> ArgumentError when checked # after type MyCallback = Callable[String, String] # declare the parameters explicitly
Defensive patterns
Strategy: validation
Validate before calling
# Ruby: reject sized tuples before the call if tuple.respond_to?(:size_type) && !tuple.size_type.nil? raise ArgumentError, 'tuple has a size constraint; strip it before callable_args?' end tuple.callable_args?(callable, guard)
Type guard
def fixed_size_tuple?(t) t.is_a?(Puppet::Pops::Types::PTupleType) && t.size_type.nil? end
Try / catch
begin tuple.callable_args?(callable, guard) rescue ArgumentError => e raise unless e.message =~ /size constraint/ PTupleType.new(tuple.types).callable_args?(callable, guard) # retry without the size type end
Prevention
- Never attach a size range to a tuple that will be used in argument position.
- Prefer explicit parameter lists in Callable types over tuple/array parameter specs.
- Treat this ArgumentError as an invariant violation: fix the type definition rather than rescuing in production code.
When it happens
Trigger: Calling tuple.callable_args?(callable, guard) in Ruby on a tuple built with a size type, e.g. PTupleType.new(types, PIntegerType.new(1, 3)); type aliases that put a sized Tuple or an Array type on the argument side of a Callable, then trigger an assignability/callability check during compilation.
Common situations: Advanced callback/dispatch type aliases (Callable[Array[String, 1]]); Ruby tools embedding pops (custom functions, linters) doing signature checks; Puppet upgrades that change when the checker invokes callable_args?.
Related errors
- Expected PCallableType or PVariantType thereof, got %{type_c
- Only Runtime type 'ruby' is supported, got #{type.runtime}
- #{my_caller.class}(): wrong argument type (#{obj.class}; is
- Init cannot be parameterized with an undefined type and addi
- Creation of new instance of type '%{type_name}' is not suppo
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/fdc3a58f0cafd8de.
Report an issue: GitHub.