nodejs/node · error · ExceptionGroup

invalid or unparsed metadata

Error message

invalid or unparsed metadata

What it means

A re-wrapping ExceptionGroup raised by Metadata.from_email after it has already checked for unparsed headers: when the subsequent cls.from_raw(raw, validate=validate) itself raises an ExceptionGroup (the 'invalid metadata' group), it is caught and re-raised with the broader message 'invalid or unparsed metadata', discarding the original cause via 'from None'.

Source

Thrown at tools/gyp/pylib/packaging/metadata.py:732

        """
        raw, unparsed = parse_email(data)

        if validate:
            exceptions: list[Exception] = []
            for unparsed_key in unparsed:
                if unparsed_key in _EMAIL_TO_RAW_MAPPING:
                    message = f"{unparsed_key!r} has invalid data"
                else:
                    message = f"unrecognized field: {unparsed_key!r}"
                exceptions.append(InvalidMetadata(unparsed_key, message))

            if exceptions:
                raise ExceptionGroup("unparsed", exceptions)

        try:
            return cls.from_raw(raw, validate=validate)
        except ExceptionGroup as exc_group:
            raise ExceptionGroup(
                "invalid or unparsed metadata", exc_group.exceptions
            ) from None

    metadata_version: _Validator[_MetadataVersion] = _Validator()
    """:external:ref:`core-metadata-metadata-version`
    (required; validated to be a valid metadata version)"""
    name: _Validator[str] = _Validator()
    """:external:ref:`core-metadata-name`
    (required; validated using :func:`~packaging.utils.canonicalize_name` and its
    *validate* parameter)"""
    version: _Validator[version_module.Version] = _Validator()
    """:external:ref:`core-metadata-version` (required)"""
    dynamic: _Validator[Optional[List[str]]] = _Validator(
        added="2.2",
    )
    """:external:ref:`core-metadata-dynamic`
    (validated against core metadata field names and lowercased)"""
    platforms: _Validator[Optional[List[str]]] = _Validator()

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Catch ExceptionGroup and read .exceptions to identify the failing raw fields.
  2. Correct the offending field values in the source METADATA/PKG-INFO.
  3. Pass validate=False to from_email to skip raw validation entirely.

Example fix

# before
meta = Metadata.from_email(data, validate=True)

# after
try:
    meta = Metadata.from_email(data, validate=True)
except ExceptionGroup as eg:
    for sub in eg.exceptions:
        print(sub)
    raise
Defensive patterns

Strategy: try-catch

Try / catch

try:
    meta = Metadata.from_email(data, validate=True)
except ExceptionGroup as eg:
    for sub in eg.exceptions:
        # sub is InvalidMetadata with .field; fix source accordingly
        pass

Prevention

When it happens

Trigger: Calling Metadata.from_email(data, validate=True) where headers parsed cleanly into raw fields but one or more of those fields then fails raw-level validation inside from_raw. The inner 'invalid metadata' group is rebranded and re-raised here.

Common situations: A well-formed email whose field values are invalid (e.g. a Version header that is not PEP 440 compliant, or a name that fails canonicalization). The from None hides the original traceback chain, so the developer sees only this top-level group.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/207e130b4128a272. Report an issue: GitHub.