{"record":{"id":"2b534c33170f7681","repo":"puppetlabs/puppet","slug":"given-variable-varname-has-illegal-name","errorCode":null,"errorMessage":"Given variable '%{varname}' has illegal name","messagePattern":"Given variable '%(.+?)' has illegal name","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pal/pal_impl.rb","lineNumber":384,"sourceCode":"      node.fact_merge(node_facts)\n      # Add server facts so $server_facts[environment] exists when doing a puppet script\n      # SCRIPT TODO: May be needed when running scripts under orchestrator. Leave it for now.\n      #\n      node.add_server_facts({})\n    end\n  end\n  private_class_method :prepare_node_facts\n\n  def self.add_variables(scope, variables)\n    return if variables.nil?\n    unless variables.is_a?(Hash)\n      raise ArgumentError, _(\"Given variables must be a hash, got %{type}\") % { type: variables.class }\n    end\n\n    rich_data_t = Puppet::Pops::Types::TypeFactory.rich_data\n    variables.each_pair do |k, v|\n      unless k =~ Puppet::Pops::Patterns::VAR_NAME\n        raise ArgumentError, _(\"Given variable '%{varname}' has illegal name\") % { varname: k }\n      end\n\n      unless rich_data_t.instance?(v)\n        raise ArgumentError, _(\"Given value for '%{varname}' has illegal type - got: %{type}\") % { varname: k, type: v.class }\n      end\n\n      scope.setvar(k, v)\n    end\n  end\n  private_class_method :add_variables\n\n  # The main routine for script compiler\n  # Picks up information from the puppet context and configures a script compiler which is given to\n  # the provided block\n  #\n  def self.main(\n    manifest:                nil,\n    facts:                   {},","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pal/pal_impl.rb#L366-L402","documentation":"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.","triggerScenarios":"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.","commonSituations":"Feeding kebab-case or camelCase keys from JSON/YAML config; Ruby hashes with symbol keys; converting HTTP query parameters into variables.","solutions":["Normalize keys to snake_case strings before the call","Convert symbol keys with transform_keys(&:to_s) and downcase as needed","Strip or replace illegal characters (- . : spaces) with underscores"],"exampleFix":"# before\nPuppet::Pal.with_script_compiler(variables: { 'max-size' => 3 }) { |c| }\n\n# after\nPuppet::Pal.with_script_compiler(variables: { 'max_size' => 3 }) { |c| }","handlingStrategy":"validation","validationCode":"variables.each_key { |k| raise ArgumentError, \"illegal variable name #{k.inspect}\" unless k.to_s =~ Puppet::Pops::Patterns::VAR_NAME }","typeGuard":"def puppet_var_name?(k)\n  k.is_a?(String) && k =~ Puppet::Pops::Patterns::VAR_NAME\nend","tryCatchPattern":null,"preventionTips":["Normalize external keys to snake_case strings before passing them as variables","Avoid symbol keys - PAL requires String keys matching the Puppet language rules"],"tags":["puppet","pal","variables","naming","validation"],"backgroundTag":"invalid-identifier","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}