nodejs/node · error · InvalidSdistFilename

Invalid sdist filename (extension must be '.tar.gz' or '.zip

Error message

Invalid sdist filename (extension must be '.tar.gz' or '.zip'): {filename}

What it means

InvalidSdistFilename raised by parse_sdist_filename when the filename ends with neither '.tar.gz' nor '.zip', the only two sdist extensions packaging recognizes.

Source

Thrown at tools/gyp/pylib/packaging/utils.py:152

        build_match = _build_tag_regex.match(build_part)
        if build_match is None:
            raise InvalidWheelFilename(
                f"Invalid build number: {build_part} in '{filename}'"
            )
        build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
    else:
        build = ()
    tags = parse_tag(parts[-1])
    return (name, version, build, tags)


def parse_sdist_filename(filename: str) -> Tuple[NormalizedName, Version]:
    if filename.endswith(".tar.gz"):
        file_stem = filename[: -len(".tar.gz")]
    elif filename.endswith(".zip"):
        file_stem = filename[: -len(".zip")]
    else:
        raise InvalidSdistFilename(
            f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
            f" {filename}"
        )

    # We are requiring a PEP 440 version, which cannot contain dashes,
    # so we split on the last dash.
    name_part, sep, version_part = file_stem.rpartition("-")
    if not sep:
        raise InvalidSdistFilename(f"Invalid sdist filename: {filename}")

    name = canonicalize_name(name_part)

    try:
        version = Version(version_part)
    except InvalidVersion as e:
        raise InvalidSdistFilename(
            f"Invalid sdist filename (invalid version): {filename}"
        ) from e

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Branch on extension: .whl -> parse_wheel_filename; .tar.gz/.zip -> parse_sdist_filename.
  2. Filter inputs to only sdist files before calling parse_sdist_filename.
  3. Catch InvalidSdistFilename and skip unknown files when scanning a directory.

Example fix

# before
name, ver = parse_sdist_filename(fname)

# after
if fname.endswith(('.tar.gz', '.zip')):
    name, ver = parse_sdist_filename(fname)
else:
    raise ValueError(f'Not an sdist: {fname}')
Defensive patterns

Strategy: type-guard

Validate before calling

def is_sdist(filename: str) -> bool:
    return filename.endswith('.tar.gz') or filename.endswith('.zip')

Type guard

from pathlib import Path
def is_sdist_path(p) -> bool:
    name = Path(p).name
    return name.endswith('.tar.gz') or name.endswith('.zip')

Try / catch

try:
    name, ver = parse_sdist_filename(fn)
except InvalidSdistFilename:
    pass  # route to wheel parser or skip

Prevention

When it happens

Trigger: Calling parse_sdist_filename on a wheel ('.whl'), a '.tar.bz2', a raw directory, or any non-sdist string.

Common situations: Routing all distribution filenames through one parser, or encountering newer/experimental sdist formats not covered by this vendored packaging version.

Related errors


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