{"record":{"id":"0693c997938584e7","repo":"puppetlabs/puppet","slug":"field-data-provider-must-begin-with-a-letter","errorCode":null,"errorMessage":"field 'data_provider' must begin with a letter","messagePattern":"field 'data_provider' must begin with a letter","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/module_tool/metadata.rb","lineNumber":212,"sourceCode":"    def validate_version(version)\n      return if SemanticPuppet::Version.valid?(version)\n\n      err = _(\"version string cannot be parsed as a valid Semantic Version\")\n      raise ArgumentError, _(\"Invalid 'version' field in metadata.json: %{err}\") % { err: err }\n    end\n\n    # Validates that the given _value_ is a symbolic name that starts with a letter\n    # and then contains only letters, digits, or underscore. Will raise an ArgumentError\n    # if that's not the case.\n    #\n    # @param value [Object] The value to be tested\n    def validate_data_provider(value)\n      if value.is_a?(String)\n        unless value =~ /^[a-zA-Z][a-zA-Z0-9_]*$/\n          if value =~ /^[a-zA-Z]/\n            raise ArgumentError, _(\"field 'data_provider' contains non-alphanumeric characters\")\n          else\n            raise ArgumentError, _(\"field 'data_provider' must begin with a letter\")\n          end\n        end\n      else\n        raise ArgumentError, _(\"field 'data_provider' must be a string\")\n      end\n    end\n\n    # Validates that the version range can be parsed by Semantic.\n    def validate_version_range(version_range)\n      SemanticPuppet::VersionRange.parse(version_range)\n    rescue ArgumentError => e\n      raise ArgumentError, _(\"Invalid 'version_range' field in metadata.json: %{err}\") % { err: e }\n    end\n  end\nend\n","sourceCodeStart":194,"sourceCodeEnd":228,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/module_tool/metadata.rb#L194-L228","documentation":"The companion branch of validate_data_provider: the value is a String but its first character is not a letter (^[^a-z] with case-insensitivity matches digits and symbols), so Puppet demands a leading letter. The rest of the string is not even examined because the format regex ^[a-zA-Z][a-zA-Z0-9_]*$ already failed at position 0.","triggerScenarios":"A metadata.json with \"data_provider\": \"4hiera\" or \"_provider\" or \"1\" — any string starting with a digit, underscore, or symbol triggers line 212.","commonSituations":"Provider names that start with a number; leading-underscore 'private' naming habits carried over from other languages; placeholder values like '123' pasted from examples.","solutions":["Rename the value to start with a letter: \"data_provider\": \"hiera4\" instead of \"4hiera\"","Remove the field if data providers are not actually used","Prefer the canonical provider name ('hiera') unless you truly have a custom provider class"],"exampleFix":"// before - metadata.json\n\"data_provider\": \"4hiera\",\n\n// after\n\"data_provider\": \"hiera4\",","handlingStrategy":"validation","validationCode":"value = JSON.parse(File.read('metadata.json'))['data_provider']\nif value.is_a?(String)\n  abort \"data_provider '#{value}' must begin with a letter\" unless value =~ /\\A[a-zA-Z]/\nend","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::ModuleTool::Metadata.from_hash('data_provider' => raw)\nrescue ArgumentError => e\n  raise unless e.message =~ /data_provider.*begin with a letter/\n  raw = \"p_#{raw}\"  # or rename to a proper provider identifier\n  retry\nend","preventionTips":["Name provider identifiers with a letter-first word ('hiera3', not '3hiera')","Delete the data_provider field when the feature is unused — it predates modern Puppet data binding","Validate template output before writing metadata.json"],"tags":["puppet","module-tool","metadata","data-provider","validation"],"backgroundTag":"invalid-metadata-field","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}