{"record":{"id":"d4f45de57eba7def","repo":"nodejs/node","slug":"invalid-metadata","errorCode":null,"errorMessage":"invalid metadata","messagePattern":"invalid metadata","errorType":"exception","errorClass":"ExceptionGroup","httpStatus":null,"severity":"error","filePath":"tools/gyp/pylib/packaging/metadata.py","lineNumber":702,"sourceCode":"                            continue\n                        field_age = _VALID_METADATA_VERSIONS.index(\n                            field_metadata_version\n                        )\n                        if field_age > metadata_age:\n                            field = _RAW_TO_EMAIL_MAPPING[key]\n                            exc = InvalidMetadata(\n                                field,\n                                \"{field} introduced in metadata version \"\n                                \"{field_metadata_version}, not {metadata_version}\",\n                            )\n                            exceptions.append(exc)\n                            continue\n                    getattr(ins, key)\n                except InvalidMetadata as exc:\n                    exceptions.append(exc)\n\n            if exceptions:\n                raise ExceptionGroup(\"invalid metadata\", exceptions)\n\n        return ins\n\n    @classmethod\n    def from_email(\n        cls, data: Union[bytes, str], *, validate: bool = True\n    ) -> \"Metadata\":\n        \"\"\"Parse metadata from email headers.\n\n        If *validate* is true, the metadata will be validated. All exceptions\n        related to validation will be gathered and raised as an :class:`ExceptionGroup`.\n        \"\"\"\n        raw, unparsed = parse_email(data)\n\n        if validate:\n            exceptions: list[Exception] = []\n            for unparsed_key in unparsed:\n                if unparsed_key in _EMAIL_TO_RAW_MAPPING:","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/tools/gyp/pylib/packaging/metadata.py#L684-L720","documentation":"An ExceptionGroup (PEP 654) raised by Metadata.from_raw when validation collects one or more InvalidMetadata exceptions during attribute/validator checks. It aggregates every per-field problem rather than failing on the first one, so the developer can see all invalid fields at once.","triggerScenarios":"Calling Metadata.from_raw(raw, validate=True) where one or more RawMetadata fields fail their _Validator checks (e.g. a field introduced in a newer metadata version than metadata_version declares, a bad version string, or a malformed value). The loop accumulates InvalidMetadata into 'exceptions' and raises this group when non-empty.","commonSituations":"Building or inspecting a package whose METADATA file was hand-edited, generated by an older tool, or has a metadata_version that is lower than fields it uses (e.g. using License-Expression without bumping metadata_version to 2.4).","solutions":["Catch ExceptionGroup and iterate exc.exceptions to see every offending field and its message.","Fix each listed field in the METADATA/PKG-INFO source so it conforms to the declared metadata_version.","If you intentionally want lenient parsing, pass validate=False to from_raw."],"exampleFix":"# before\nmeta = Metadata.from_raw(raw, validate=True)\n\n# after\ntry:\n    meta = Metadata.from_raw(raw, validate=True)\nexcept ExceptionGroup as eg:\n    for e in eg.exceptions:\n        print(e.field, str(e))\n    raise","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    meta = Metadata.from_raw(raw, validate=True)\nexcept ExceptionGroup as eg:\n    fields = [(e.field, str(e)) for e in eg.exceptions if isinstance(e, InvalidMetadata)]\n    # report all fields, then decide","preventionTips":["Generate METADATA with a PEP 621-compliant build backend rather than hand-editing.","Keep metadata_version consistent with the fields you use.","In CI, validate metadata with packaging before publishing."],"tags":["packaging","metadata","validation","exceptiongroup"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}