puppetlabs/puppet · error · Puppet::ParseError
Cannot assign to a numeric match result variable '$%{name}'
Error message
Cannot assign to a numeric match result variable '$%{name}' What it means
Raised by Scope#setvar when the variable name consists solely of digits (matches /^[0-9]+$/). Numeric variable names $0..$n are reserved for regex match captures set by MatchScope; they are populated automatically when a =~ or !~ expression with capture groups runs, and Puppet forbids explicit assignment to them. Note this guard lives in setvar, so it applies to DSL assignments and Ruby functions alike.
Source
Thrown at lib/puppet/parser/scope.rb:776
end
end
private :transform_setting
VARNAME_TRUSTED = 'trusted'
VARNAME_FACTS = 'facts'
VARNAME_SERVER_FACTS = 'server_facts'
RESERVED_VARIABLE_NAMES = [VARNAME_TRUSTED, VARNAME_FACTS].freeze
TYPENAME_CLASS = 'Class'
TYPENAME_NODE = 'Node'
# Set a variable in the current scope. This will override settings
# in scopes above, but will not allow variables in the current scope
# to be reassigned.
# It's preferred that you use self[]= instead of this; only use this
# when you need to set options.
def setvar(name, value, options = EMPTY_HASH)
if name =~ /^[0-9]+$/
raise Puppet::ParseError, _("Cannot assign to a numeric match result variable '$%{name}'") % { name: name } # unless options[:ephemeral]
end
unless name.is_a? String
raise Puppet::ParseError, _("Scope variable name %{name} is a %{class_type}, not a string") % { name: name.inspect, class_type: name.class }
end
# Check for reserved variable names
if (name == VARNAME_TRUSTED || name == VARNAME_FACTS) && !options[:privileged]
raise Puppet::ParseError, _("Attempt to assign to a reserved variable name: '%{name}'") % { name: name }
end
# Check for server_facts reserved variable name
if name == VARNAME_SERVER_FACTS && !options[:privileged]
raise Puppet::ParseError, _("Attempt to assign to a reserved variable name: '%{name}'") % { name: name }
end
table = effective_symtable(options[:ephemeral])
if table.bound?(name)
error = Puppet::ParseError.new(_("Cannot reassign variable '$%{name}'") % { name: name })View on GitHub (pinned to e227c27540)
Solutions
- Rename the variable to a non-numeric name: `$match1` instead of `$1`.
- If you want regex captures, trigger them with a match expression instead of assigning: `$content =~ /(a+)/` then read $1.
- In Ruby functions, reject or prefix numeric names before setvar: `name = "v#{name}" if name =~ /^[0-9]+$/`.
Example fix
# before $1 = 'primary' # Cannot assign to a numeric match result variable '$1' # after $primary = 'primary' # or set captures via an actual match: 'primary' =~ /^(.+)$/ # now $1 == 'primary'
Defensive patterns
Strategy: validation
Validate before calling
# Manifests: never use numeric names; if generating names programmatically:
# name = "v#{raw}" if raw =~ /^[0-9]+$/
# Ruby guard before assignment:
raise ArgumentError, 'numeric var' if name =~ /^[0-9]+$/
scope.setvar(name, value) unless name =~ /^[0-9]+$/ Prevention
- Reserve $0..$n exclusively for regex captures; use named captures (`$<name>`-style facts) or named variables otherwise.
- Sanitize external keys before creating scope variables from them.
- Read $0 only after a successful =~ match in the same scope.
When it happens
Trigger: Manifest code `$1 = 'foo'` or `$0 = generate_title()`; Ruby code calling `scope.setvar('2', 'x')` or `scope['3'] = value` on a parser scope. Also a function looping over user-supplied names that happen to be numeric strings.
Common situations: Porting templates/scripts that used numbered variables as throwaway names; Ruby functions auto-creating variables from external data (ERB, YAML keys like '1') without sanitizing names; confusing numeric match variables with regular variables in examples copied from regex-heavy manifests.
Related errors
- Undefined variable '%{name}'; %{reason}
- Undefined variable '%{name}'; %{reason}
- Attempt to assign to a reserved variable name: '%{name}'
- Given variables must be a hash, got %{type}
- Given variable '%{varname}' has illegal name
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/0d4f8a18e9f84062.
Report an issue: GitHub.