{"record":{"id":"d332fe76a25b1dee","repo":"pypa/pip","slug":"invalid-build-number-build-part-in-filename-r","errorCode":null,"errorMessage":"Invalid build number: {build_part} in {filename!r}","messagePattern":"Invalid build number: (.+?) in (.+?)","errorType":"validation","errorClass":"InvalidWheelFilename","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/utils.py","lineNumber":285,"sourceCode":"    parts = filename.split(\"-\", dashes - 2)\n    name_part = parts[0]\n    # See PEP 427 for the rules on escaping the project name.\n    if \"__\" in name_part or _wheel_name_regex.match(name_part) is None:\n        raise InvalidWheelFilename(f\"Invalid project name: {filename!r}\")\n    name = canonicalize_name(name_part)\n\n    try:\n        version = Version(parts[1])\n    except InvalidVersion as e:\n        raise InvalidWheelFilename(\n            f\"Invalid wheel filename (invalid version): {filename!r}\"\n        ) from e\n\n    if dashes == 5:\n        build_part = parts[2]\n        build_match = _build_tag_regex.match(build_part)\n        if build_match is None:\n            raise InvalidWheelFilename(\n                f\"Invalid build number: {build_part} in {filename!r}\"\n            )\n        build = cast(\"BuildTag\", (int(build_match.group(1)), build_match.group(2)))\n    else:\n        build = ()\n    tag_str = parts[-1]\n    try:\n        tags = parse_tag(tag_str, validate_order=validate_order)\n    except UnsortedTagsError:\n        raise InvalidWheelFilename(\n            f\"Invalid wheel filename (compressed tag set components must be in \"\n            f\"sorted order per PEP 425): {filename!r}\"\n        ) from None\n    except InvalidTag:\n        raise InvalidWheelFilename(\n            f\"Invalid wheel filename (invalid tag component): {filename!r}\"\n        ) from None\n    return (name, version, build, tags)","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/utils.py#L267-L303","documentation":"Raised by parse_wheel_filename() when a build tag is present (5 dashes in the stem) but the build-segment string does not match _build_tag_regex (\\d+)(.*)  at utils.py:283-287. Per PEP 427, the build tag must start with a digit. If _build_tag_regex.match() returns None, the build number is invalid.","triggerScenarios":"A wheel filename with 5 dashes where the build segment does not begin with a digit, e.g. 'foo-1.0-abc-py3-none-any.whl' where build part 'abc' fails the regex because it has no leading digit.","commonSituations":"A build backend that emits a build tag without a numeric prefix, or a manually renamed wheel file where a non-numeric token was placed in the build-tag position.","solutions":["Ensure the build-tag segment starts with one or more digits (e.g. '1', '2final', '100abc').","Remove the build tag entirely if you do not need one (go back to 4 dashes).","Move non-numeric build metadata into the version's local segment instead."],"exampleFix":"// before\nparse_wheel_filename('foo-1.0-abc-py3-none-any.whl')\n// after\nparse_wheel_filename('foo-1.0-1abc-py3-none-any.whl')","handlingStrategy":"validation","validationCode":"import re\n_build_tag_regex = re.compile(r\"(\\d+)(.*)\", re.ASCII)\n\ndef safe_parse_wheel(filename: str):\n    stem = filename[:-4]\n    dashes = stem.count(\"-\")\n    if dashes == 5:\n        build_part = stem.split(\"-\", 3)[2]\n        if _build_tag_regex.match(build_part) is None:\n            raise ValueError(f\"Build tag must start with a digit: {build_part!r}\")\n    return parse_wheel_filename(filename)","typeGuard":"import re\n\ndef has_valid_build_tag(filename: str) -> bool:\n    if not isinstance(filename, str) or not filename.endswith(\".whl\"):\n        return False\n    stem = filename[:-4]\n    if stem.count(\"-\") != 5:\n        return True  # no build tag present\n    build_part = stem.split(\"-\", 3)[2]\n    return bool(re.match(r\"\\d+\", build_part))","tryCatchPattern":"from packaging.utils import InvalidWheelFilename\n\ntry:\n    parse_wheel_filename(filename)\nexcept InvalidWheelFilename as e:\n    if \"Invalid build number\" in str(e):\n        logger.error(\"Wheel build tag must start with a digit: %s\", filename)\n    raise","preventionTips":["Ensure build-tag segments start with digits (e.g. '1', '2final')","Omit the build tag entirely (use 4 dashes) if none is needed","Move non-numeric metadata into the version's local segment"],"tags":["wheel","filename","build-tag","packaging","pep427"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}