{"record":{"id":"9c1be34feb460817","repo":"puppetlabs/puppet","slug":"cannot-use-undef-as-a-class-name","errorCode":null,"errorMessage":"Cannot use undef as a class name","messagePattern":"Cannot use undef as a class name","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/parser/scope.rb","lineNumber":1084,"sourceCode":"\n  # Transforms references to classes to the form suitable for\n  # lookup in the compiler.\n  #\n  # Makes names passed in the names array absolute if they are relative.\n  #\n  # Transforms Class[] and Resource[] type references to class name\n  # or raises an error if a Class[] is unspecific, if a Resource is not\n  # a 'class' resource, or if unspecific (no title).\n  #\n  #\n  # @param names [Array<String>] names to (optionally) make absolute\n  # @return [Array<String>] names after transformation\n  #\n  def transform_and_assert_classnames(names)\n    names.map do |name|\n      case name\n      when NilClass\n        raise ArgumentError, _(\"Cannot use undef as a class name\")\n      when String\n        raise ArgumentError, _(\"Cannot use empty string as a class name\") if name.empty?\n\n        name.sub(/^([^:]{1,2})/, '::\\1')\n\n      when Puppet::Resource\n        assert_class_and_title(name.type, name.title)\n        name.title.sub(/^([^:]{1,2})/, '::\\1')\n\n      when Puppet::Pops::Types::PClassType\n        # TRANSLATORS \"Class\" and \"Type\" are Puppet keywords and should not be translated\n        raise ArgumentError, _(\"Cannot use an unspecific Class[] Type\") unless name.class_name\n\n        name.class_name.sub(/^([^:]{1,2})/, '::\\1')\n\n      when Puppet::Pops::Types::PResourceType\n        assert_class_and_title(name.type_name, name.title)\n        name.title.sub(/^([^:]{1,2})/, '::\\1')","sourceCodeStart":1066,"sourceCodeEnd":1102,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/parser/scope.rb#L1066-L1102","documentation":"Raised by Scope#transform_and_assert_classnames when an element of the names array is nil (NilClass branch). This method normalizes arguments to include/contain/require-style class references; a nil element means the caller asked to include 'undef', which has no meaningful class target. Note it raises ArgumentError rather than Puppet::ParseError, so it surfaces as a plain evaluation error.","triggerScenarios":"`include $maybe` where $maybe is undef (variable never set, or set to undef explicitly); `include $var` where Hiera lookup returned nothing; `contain Class[$missing]` with $missing undef; API calls `scope.transform_and_assert_classnames([nil])` or functions like realize() receiving nil.","commonSituations":"Optional classes driven by Hiera keys that are absent ('include' of a lookup with no default); strict_variables runs turning a previously-silent nil into a visible nil; hiera_array/hiera_hash returning empty and code doing `include $list[0]`.","solutions":["Guard the include: `if $maybe { include $maybe }` or `if $maybe != undef { include $maybe }`.","Give the lookup a default: `$maybe = lookup('classes::extra', String, 'first', 'absent')` then conditionally include.","Filter nils out of lists before iterating: `$classes = lookup('classes', Array, 'unique', []).filter |$c| { $c != undef }`."],"exampleFix":"# before\ninclude $optional_class   # $optional_class is undef -> Cannot use undef as a class name\n\n# after\n$optional_class = lookup('profile::optional', Optional[String], 'first', undef)\nif $optional_class {\n  include $optional_class\n}","handlingStrategy":"type-guard","validationCode":"$name = lookup('opt::class', Optional[String], 'first', undef)\ninclude $name if $name != undef","typeGuard":"# Puppet DSL narrowing — only include when a real name exists:\nif $maybe =~ NonEmptyString {\n  include $maybe\n}\n# Ruby API:\ndef includable?(name)\n  name.is_a?(String) && !name.empty?\nend","tryCatchPattern":null,"preventionTips":["Type optional Hiera lookups as Optional[String] with an undef default instead of letting them leak nil into include.","Filter nil/empty out of data-driven class lists before iterating (`filter |$c| { $c =~ NonEmptyString }`).","In Ruby, reject nil titles before constructing class references."],"tags":["puppet","class-reference","undef","include","hiera"],"backgroundTag":"invalid-class-reference","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}