{"id":"c3aae0392376f948","repo":"pypa/pip","slug":"invalid-or-unparsed-metadata","errorCode":null,"errorMessage":"invalid or unparsed metadata","messagePattern":"invalid or unparsed metadata","errorType":"exception","errorClass":"ExceptionGroup","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/metadata.py","lineNumber":843,"sourceCode":"\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            with _ErrorCollector().on_exit(\"unparsed\") as collector:\n                for unparsed_key in unparsed:\n                    if unparsed_key in _EMAIL_TO_RAW_MAPPING:\n                        message = f\"{unparsed_key!r} has invalid data\"\n                    else:\n                        message = f\"unrecognized field: {unparsed_key!r}\"\n                    collector.error(InvalidMetadata(unparsed_key, message))\n\n        try:\n            return cls.from_raw(raw, validate=validate)\n        except ExceptionGroup as exc_group:\n            raise ExceptionGroup(\n                \"invalid or unparsed metadata\", exc_group.exceptions\n            ) from None\n\n    metadata_version: _Validator[_MetadataVersion] = _Validator()\n    \"\"\":external:ref:`core-metadata-metadata-version`\n    (required; validated to be a valid metadata version)\"\"\"\n    # `name` is not normalized/typed to NormalizedName so as to provide access to\n    # the original/raw name.\n    name: _Validator[str] = _Validator()\n    \"\"\":external:ref:`core-metadata-name`\n    (required; validated using :func:`~packaging.utils.canonicalize_name` and its\n    *validate* parameter)\"\"\"\n    version: _Validator[version_module.Version] = _Validator()\n    \"\"\":external:ref:`core-metadata-version` (required)\"\"\"\n    dynamic: _Validator[list[str] | None] = _Validator(\n        added=\"2.2\",\n    )\n    \"\"\":external:ref:`core-metadata-dynamic`","sourceCodeStart":825,"sourceCodeEnd":861,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/packaging/metadata.py#L825-L861","documentation":"Re-raised as ExceptionGroup('invalid or unparsed metadata') by Metadata.from_email after from_raw has already collected individual InvalidMetadata exceptions. It bundles all field-level problems (invalid values, unparsed fields, type mismatches) into one group so callers see every defect rather than just the first.","triggerScenarios":"Calling from_email on METADATA with validate=True when fields are malformed (bad version, duplicate keys, invalid classifier, unknown fields, etc.). Any case where from_raw raises ExceptionGroup of InvalidMetadata instances.","commonSituations":"Consuming third-party package metadata; validating pyproject during build; CI linting wheels with twine check.","solutions":["Inspect exc.exceptions: each is an InvalidMetadata keyed by field; fix them one by one.","Run twine check / build locally to surface all metadata issues before publishing.","Pass validate=False if you only need best-effort parsing, then handle unparsed fields manually.","Generate metadata with a conformant backend (setuptools, hatchling, flit) rather than hand-writing METADATA."],"exampleFix":"# before\nmd = Metadata.from_email(raw, validate=True)\n# after\ntry:\n    md = Metadata.from_email(raw, validate=True)\nexcept ExceptionGroup as eg:\n    for sub in eg.exceptions:\n        print(sub)\n    raise","handlingStrategy":"try-catch","validationCode":"def validate_metadata(raw):\n    try:\n        Metadata.from_email(raw, validate=True)\n        return []\n    except ExceptionGroup as eg:\n        return eg.exceptions","typeGuard":null,"tryCatchPattern":"try:\n    md = Metadata.from_email(raw, validate=True)\nexcept ExceptionGroup as eg:\n    for sub in eg.exceptions:\n        print(f'{sub.field}: {sub}')  # InvalidMetadata has .field\n    raise","preventionTips":["Generate metadata with a conformant PEP 621 backend.","Run twine check / build before publishing.","Iterate over ExceptionGroup.exceptions to fix all defects at once.","Use validate=False only for best-effort parsing and handle unparsed fields."],"tags":["metadata","validation","exceptiongroup","pep643"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}