puppetlabs/puppet · error · ArgumentError
A required parameter cannot be added after an optional param
Error message
A required parameter cannot be added after an optional parameter
What it means
In a dispatch DSL block, param declares a required positional parameter. The builder tracks optionality with @min and @max; when @min != @max an optional parameter was already declared. A required parameter after an optional one is impossible to bind at call time, so Puppet rejects it at definition time with this ArgumentError.
Source
Thrown at lib/puppet/functions.rb:415
# @api private
def initialize(dispatcher, all_callables, loader)
@all_callables = all_callables
@dispatcher = dispatcher
@loader = loader
end
# Defines a required positional parameter with _type_ and _name_.
#
# @param type [String] The type specification for the parameter.
# @param name [Symbol] The name of the parameter. This is primarily used
# for error message output and does not have to match an implementation
# method parameter.
# @return [Void]
#
# @api public
def param(type, name)
internal_param(type, name)
raise ArgumentError, _('A required parameter cannot be added after an optional parameter') if @min != @max
@min += 1
@max += 1
end
alias required_param param
# Defines an optional positional parameter with _type_ and _name_.
# May not be followed by a required parameter.
#
# @param type [String] The type specification for the parameter.
# @param name [Symbol] The name of the parameter. This is primarily used
# for error message output and does not have to match an implementation
# method parameter.
# @return [Void]
#
# @api public
def optional_param(type, name)
internal_param(type, name)View on GitHub (pinned to e227c27540)
Solutions
- Reorder the declarations: all param entries first, then optional_param entries.
- If the new argument must be last and mandatory, promote the earlier optional_param to param as well (note: breaking change for callers).
- If both call shapes must stay supported, declare two separate dispatch blocks with different arities instead.
Example fix
# before dispatch :run do optional_param 'String', :suffix param 'String', :base # raises: required after optional end # after: required parameters come first dispatch :run do param 'String', :base optional_param 'String', :suffix end
Defensive patterns
Strategy: validation
Validate before calling
# Review-time ordering rule: required params first, then optional, then repeated, then block # CI grep: fail if an optional_param line appears before a param line in one dispatch ! grep -Pzo 'dispatch[^}]*optional_param[^}]*\n[^}]*\sparam ' lib/puppet/functions/**/*.rb
Prevention
- Memorize the legal order: param, optional_param, repeated, block_param.
- When adding a mandatory argument, re-check the whole block, not just the new line.
- Use two dispatch blocks to support old and new call shapes instead of reordering optionals.
When it happens
Trigger: dispatch :m do optional_param 'String', :b; param 'String', :a end. The required :a is declared after the optional :b, so the raise fires.
Common situations: Adding a new mandatory argument to a signature that already ends with optional arguments; merges or edits that reorder param blocks mechanically.
Related errors
- Parameters cannot be added after a block parameter
- A required repeated parameter cannot be added after an optio
- Parameters cannot be added after a repeated parameter
- Parameter 'type' must be a String reference to a Puppet Data
- Function Load Error for function '%{function_name}': %{messa
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/88813eeb7ac0cc83.
Report an issue: GitHub.