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'.

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.

Appendix: 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)