{"record":{"id":"3aae7c3e252c3cd4","repo":"puppetlabs/puppet","slug":"puppet-tasks-unreadable-metadata","errorCode":"puppet.tasks/unreadable-metadata","errorMessage":"Error reading metadata: %{message}","messagePattern":"Error reading metadata: %(.+?)","errorType":"validation","errorClass":"Puppet::Module::Task::InvalidMetadata","httpStatus":null,"severity":"warning","filePath":"lib/puppet/module/task.rb","lineNumber":248,"sourceCode":"        raise InvalidName, _(\"Task names must start with a lowercase letter and be composed of only lowercase letters, numbers, and underscores\")\n      end\n\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)","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/module/task.rb#L230-L266","documentation":"Raised as Puppet::Error by Config#parse_directive when var is anything other than 'type', 'url', or 'debug'. In practice it is unreachable through Config#read because the preceding line regex only lets type|url|debug lines reach parse_directive; the branch is defensive code against future directives or direct calls. If you see it, something is calling parse_directive directly with an unknown key.","triggerScenarios":"Custom code invoking Puppet::Util::NetworkDevice::Config#parse_directive(device, 'user', 'admin', line) or similar with an unsupported var; a patched/older read regex that forwards new directive names to an unpatched parse_directive after a partial upgrade.","commonSituations":"Monkey-patches or vendored forks that add directives to the regex but not to the case statement; version skew between a patched config reader and the stock parser.","solutions":["If calling parse_directive directly, pass only 'type', 'url', or 'debug' as var","If you extended the reader regex, extend parse_directive's case with your new key in the same patch","Un-vendor/align Puppet versions so the regex and the case statement come from the same release"],"exampleFix":"# before\nconfig.parse_directive(device, 'user', 'admin', 4) # raises Invalid argument 'user'\n\n# after\nconfig.parse_directive(device, 'url', 'ssh://admin@sw01.example.com', 4)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"SUPPORTED_DIRECTIVES = %w[type url debug].freeze\n\ndef supported_directive?(var)\n  SUPPORTED_DIRECTIVES.include?(var)\nend\n\nconfig.parse_directive(device, var, value, line) if supported_directive?(var)","tryCatchPattern":"begin\n  config.parse_directive(device, var, value, line)\nrescue Puppet::Error => e\n  raise unless e.message =~ /Invalid argument/\n  Puppet.debug(\"ignoring unsupported device.conf directive #{var}\")\nend","preventionTips":["If you patch the device.conf reader regex, patch parse_directive's case in the same change","Do not call parse_directive with ad-hoc keys; extend both sides atomically","Avoid vendoring old copies of config.rb alongside a newer Puppet"],"tags":["puppet","network-device","device-conf","unsupported-directive","defensive-code"],"backgroundTag":"unsupported-config-key","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}