nodejs/node · error · ExceptionGroup

invalid metadata

Error message

invalid metadata

What it means

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.

Solutions

  1. Catch ExceptionGroup and iterate exc.exceptions to see every offending field and its message.
  2. Fix each listed field in the METADATA/PKG-INFO source so it conforms to the declared metadata_version.
  3. If you intentionally want lenient parsing, pass validate=False to from_raw.

Example fix

# before
meta = Metadata.from_raw(raw, validate=True)

# after
try:
    meta = Metadata.from_raw(raw, validate=True)
except ExceptionGroup as eg:
    for e in eg.exceptions:
        print(e.field, str(e))
    raise
Defensive patterns

Strategy: try-catch

Try / catch

try:
    meta = Metadata.from_raw(raw, validate=True)
except ExceptionGroup as eg:
    fields = [(e.field, str(e)) for e in eg.exceptions if isinstance(e, InvalidMetadata)]
    # report all fields, then decide

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


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

Appendix: source

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

                            continue
                        field_age = _VALID_METADATA_VERSIONS.index(
                            field_metadata_version
                        )
                        if field_age > metadata_age:
                            field = _RAW_TO_EMAIL_MAPPING[key]
                            exc = InvalidMetadata(
                                field,
                                "{field} introduced in metadata version "
                                "{field_metadata_version}, not {metadata_version}",
                            )
                            exceptions.append(exc)
                            continue
                    getattr(ins, key)
                except InvalidMetadata as exc:
                    exceptions.append(exc)

            if exceptions:
                raise ExceptionGroup("invalid metadata", exceptions)

        return ins

    @classmethod
    def from_email(
        cls, data: Union[bytes, str], *, validate: bool = True
    ) -> "Metadata":
        """Parse metadata from email headers.

        If *validate* is true, the metadata will be validated. All exceptions
        related to validation will be gathered and raised as an :class:`ExceptionGroup`.
        """
        raw, unparsed = parse_email(data)

        if validate:
            exceptions: list[Exception] = []
            for unparsed_key in unparsed:
                if unparsed_key in _EMAIL_TO_RAW_MAPPING:

View on GitHub (pinned to 1b2de5e052)