puppetlabs/puppet · error · Puppet::Error
%{callee}: expects a value for parameter $%{to}
Error message
%{callee}: expects a value for parameter $%{to} What it means
Raised by Puppet::Parser::Scope::ParameterScope#parameter_reference_failure while a class/define parameter default is being evaluated. Parameters are evaluated strictly in declaration order; if the default expression of parameter $from reads parameter $to, and $to is declared EARLIER (keys.index(to) < keys.index(from)) but still unassigned, Puppet knows $to can never receive a value from this evaluation, so the callee is simply missing a required argument. The message names the callee (class/define/lambda) and the parameter that never got a value.
Source
Thrown at lib/puppet/parser/scope.rb:212
end
parameter_reference_failure(name, bad)
end
end
def evaluate(name, expression, scope, evaluator)
scope.with_guarded_scope do
bad = catch(:unevaluated_parameter) do
scope.new_match_scope(nil)
return as_read_only { evaluator.evaluate(expression, scope) }
end
parameter_reference_failure(name, bad)
end
end
def parameter_reference_failure(from, to)
# Parameters are evaluated in the order they have in the @params hash.
keys = @params.keys
raise Puppet::Error, _("%{callee}: expects a value for parameter $%{to}") % { callee: @callee_name, to: to } if keys.index(to) < keys.index(from)
raise Puppet::Error, _("%{callee}: default expression for $%{from} tries to illegally access not yet evaluated $%{to}") % { callee: @callee_name, from: from, to: to }
end
private :parameter_reference_failure
def initialize(parent, callee_name, param_names)
super(parent)
@callee_name = callee_name
@params = {}
param_names.each { |name| @params[name] = Access.new }
end
def [](name)
access = @params[name]
return super if access.nil?
throw(:unevaluated_parameter, name) unless access.assigned?
access.valueView on GitHub (pinned to e227c27540)
Solutions
- Pass an explicit value for the named parameter at the declaration site: `class { 'example': b => 10 }` (include cannot pass parameters).
- Give the referenced parameter a default so it is always assigned: `class example($b = 5, $a = $b)`.
- Add a matching Hiera key (e.g. 'example::b' in the environment data) so automatic parameter lookup supplies the value.
- Restructure so the referencing default does not depend on a defaulted-or-missing earlier parameter (compute both from a shared expression or a custom function).
Example fix
# before
# site.pp
include example # error: example: expects a value for parameter $b
# class example($b, $a = $b) { }
# after
class { 'example':
b => 10,
} Defensive patterns
Strategy: validation
Validate before calling
# site.pp — always pass required params explicitly instead of bare include # lint: check classes whose param defaults reference other params # rough static check of a manifest's parameter list: # puppet parser validate catches syntax only; use catalog preview: # puppet apply --noop --execute "include example" # fails fast with the parameter name before production runs.
Prevention
- Never rely on a later parameter's default to feed an earlier required parameter — either default it or always pass it.
- Prefer class-resource declarations (`class { 'x': param => v }`) over `include` in code paths where parameters matter.
- Keep Hiera keys aligned with every class parameter that lacks a default (example::b style).
- Add a smoke-test profile in CI that compiles representative nodes to catch missing-parameter errors before deploy.
When it happens
Trigger: Declaring `class example($b, $a = $b) {}` and including it without a value for $b (e.g. bare `include example`). When $a's default reads $b, ParameterScope#[] throws :unevaluated_parameter because $b's Access was never assigned; since $b precedes $a, evaluate() raises 'example: expects a value for parameter $b'. Same for defines: `define d($b, $a = $b)` used as `d { 'x': }`.
Common situations: Refactoring a class so a previously-defaulted parameter loses its default while another parameter still references it; copying a define signature and forgetting to pass all required parameters at call sites; relying on Hiera automatic parameter lookup silently failing because no matching key exists for the referenced parameter.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- %{callee}: default expression for $%{from} tries to illegall
- Function Load Error for function '%{function_name}': %{messa
- A required parameter cannot be added after an optional param
- block_param accepts max 2 arguments (type, name), got %{size
- Attempt to redefine block
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/93709df077c565bf.
Report an issue: GitHub.