puppetlabs/puppet · error · ArgumentError

Given variable ' ' has illegal name

Error message

Given variable '%{varname}' has illegal name

What it means

Every key in the PAL variables hash must match Puppet::Pops::Patterns::VAR_NAME - a legal Puppet language variable name (starts with a lowercase letter or underscore, then only letters, digits and underscores). Any other key raises ArgumentError with the offending name. Symbol keys also fail the match.

Solutions

  1. Normalize keys to snake_case strings before the call
  2. Convert symbol keys with transform_keys(&:to_s) and downcase as needed
  3. Strip or replace illegal characters (- . : spaces) with underscores

Example fix

# before
Puppet::Pal.with_script_compiler(variables: { 'max-size' => 3 }) { |c| }

# after
Puppet::Pal.with_script_compiler(variables: { 'max_size' => 3 }) { |c| }
Defensive patterns

Strategy: validation

Validate before calling

variables.each_key { |k| raise ArgumentError, "illegal variable name #{k.inspect}" unless k.to_s =~ Puppet::Pops::Patterns::VAR_NAME }

Type guard

def puppet_var_name?(k)
  k.is_a?(String) && k =~ Puppet::Pops::Patterns::VAR_NAME
end

Prevention

When it happens

Trigger: variables: { 'my-var' => 1 } (dash), { 'Foo' => 1 } (uppercase start), { '2fast' => 1 } (leading digit), or symbol keys like { foo: 1 } because Symbol does not match the pattern.

Common situations: Feeding kebab-case or camelCase keys from JSON/YAML config; Ruby hashes with symbol keys; converting HTTP query parameters into variables.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/2b534c33170f7681. Report an issue: GitHub.

Appendix: source

Thrown at lib/puppet/pal/pal_impl.rb:384

      node.fact_merge(node_facts)
      # Add server facts so $server_facts[environment] exists when doing a puppet script
      # SCRIPT TODO: May be needed when running scripts under orchestrator. Leave it for now.
      #
      node.add_server_facts({})
    end
  end
  private_class_method :prepare_node_facts

  def self.add_variables(scope, variables)
    return if variables.nil?
    unless variables.is_a?(Hash)
      raise ArgumentError, _("Given variables must be a hash, got %{type}") % { type: variables.class }
    end

    rich_data_t = Puppet::Pops::Types::TypeFactory.rich_data
    variables.each_pair do |k, v|
      unless k =~ Puppet::Pops::Patterns::VAR_NAME
        raise ArgumentError, _("Given variable '%{varname}' has illegal name") % { varname: k }
      end

      unless rich_data_t.instance?(v)
        raise ArgumentError, _("Given value for '%{varname}' has illegal type - got: %{type}") % { varname: k, type: v.class }
      end

      scope.setvar(k, v)
    end
  end
  private_class_method :add_variables

  # The main routine for script compiler
  # Picks up information from the puppet context and configures a script compiler which is given to
  # the provided block
  #
  def self.main(
    manifest:                nil,
    facts:                   {},

View on GitHub (pinned to e227c27540)