{"record":{"id":"58bbccb0c62cb7b8","repo":"puppetlabs/puppet","slug":"puppet-tasks-unparseable-metadata","errorCode":"puppet.tasks/unparseable-metadata","errorMessage":"err.message","messagePattern":"err\\.message","errorType":"validation","errorClass":"Puppet::Module::Task::InvalidMetadata","httpStatus":null,"severity":"error","filePath":"lib/puppet/module/task.rb","lineNumber":250,"sourceCode":"\n      name = task_name == \"init\" ? pup_module.name : \"#{pup_module.name}::#{task_name}\"\n\n      @module = pup_module\n      @name = name\n      @metadata_file = metadata_file\n      @module_executables = module_executables || []\n    end\n\n    def self.read_metadata(file)\n      if file\n        content = Puppet::FileSystem.read(file, :encoding => 'utf-8')\n        content.empty? ? {} : Puppet::Util::Json.load(content)\n      end\n    rescue SystemCallError, IOError => err\n      msg = _(\"Error reading metadata: %{message}\" % { message: err.message })\n      raise InvalidMetadata.new(msg, 'puppet.tasks/unreadable-metadata')\n    rescue Puppet::Util::Json::ParseError => err\n      raise InvalidMetadata.new(err.message, 'puppet.tasks/unparseable-metadata')\n    end\n\n    def metadata\n      @metadata ||= self.class.read_metadata(@metadata_file)\n    end\n\n    def files\n      @files ||= self.class.find_files(@name, @module.tasks_directory, metadata, @module_executables, environment_name)\n    end\n\n    def validate\n      files\n      true\n    end\n\n    def ==(other)\n      name == other.name &&\n        self.module == other.module","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/module/task.rb#L232-L268","documentation":"Raised as Puppet::Util::Package::Version::Debian::ValidationFailure (an ArgumentError) by Debian.parse when the argument is not a String — the very first check in parse, before the epoch/upstream/revision regex is applied. nil, symbols, integers, or floats all fail here; a String that merely fails the version grammar raises the sibling error 'as a debian version identifier' instead. The returned instance is frozen and built from epoch.to_i plus the captured groups.","triggerScenarios":"Calling Puppet::Util::Package::Version::Debian.parse(nil), parse(:present), or parse(1.9) — typically because a package ensure/Version value arrived untyped from Hiera, an ENC, or user input and was passed through without coercion. Also parse(v) where v is a Puppet::Parser::AST wrapper or params class instead of a plain string.","commonSituations":"Hiera lookups returning nil for an optional version key that is forwarded anyway; package providers receiving `ensure => latest` symbols into version comparison paths; custom types passing numeric versions (1.9) where the Debian comparison class expects '1.9'.","solutions":["Coerce before parsing: pass `ver.to_s` (and skip the call when ver.nil?) so parse always receives a String","Default optional Hiera keys to a real version string or handle nil explicitly at the call site","If you meant a non-Debian scheme, use the matching class (Version::Rpm, Version::Gem, Version::Pip) — they all have the same String contract"],"exampleFix":"# before\nver = Puppet::Util::Package::Version::Debian.parse(params['version']) # nil -> ValidationFailure\n\n# after\nraw = params['version']\nver = raw.nil? ? nil : Puppet::Util::Package::Version::Debian.parse(raw.to_s)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def debian_version_string?(ver)\n  ver.is_a?(String) && !ver.empty? && ver.match?(Puppet::Util::Package::Version::Debian::REGEX_FULL_RX)\nend\n\nPuppet::Util::Package::Version::Debian.parse(v) if debian_version_string?(v)","tryCatchPattern":"begin\n  Puppet::Util::Package::Version::Debian.parse(ver)\nrescue Puppet::Util::Package::Version::Debian::ValidationFailure => e\n  raise unless e.message =~ /as a string/\n  Puppet::Util::Package::Version::Debian.parse(ver.to_s)\nend","preventionTips":["Coerce inputs to String (ver.to_s) and nil-check before calling any Version.parse","Give optional Hiera version keys explicit string defaults","Remember all Version classes (Debian/Rpm/Gem/Pip) share the String-only contract"],"tags":["puppet","package-version","debian","type-validation","argument-error"],"backgroundTag":"package-version-parse-error","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}