{"record":{"id":"efd9347ba1d420e6","repo":"pypa/pip","slug":"post-must-be-non-negative-integer-got-value","errorCode":null,"errorMessage":"post must be non-negative integer, got {value}","messagePattern":"post must be non-negative integer, got (.+?)","errorType":"validation","errorClass":"InvalidVersion","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/packaging/version.py","lineNumber":309,"sourceCode":"        if (\n            isinstance(letter, str)\n            and (normalized := normalize_pre(letter)) in {\"a\", \"b\", \"rc\"}\n            and isinstance(number, int)\n            and number >= 0\n        ):\n            # type checkers can't infer the Literal type here on letter\n            return (normalized, number)  # type: ignore[return-value]\n    msg = f\"pre must be a tuple of ('a'|'b'|'rc', non-negative int), got {value}\"\n    raise InvalidVersion(msg)\n\n\ndef _validate_post(value: object, /) -> tuple[Literal[\"post\"], int] | None:\n    if value is None:\n        return value\n    if isinstance(value, int) and value >= 0:\n        return (\"post\", value)\n    msg = f\"post must be non-negative integer, got {value}\"\n    raise InvalidVersion(msg)\n\n\ndef _validate_dev(value: object, /) -> tuple[Literal[\"dev\"], int] | None:\n    if value is None:\n        return value\n    if isinstance(value, int) and value >= 0:\n        return (\"dev\", value)\n    msg = f\"dev must be non-negative integer, got {value}\"\n    raise InvalidVersion(msg)\n\n\ndef _validate_local(value: object, /) -> LocalType | None:\n    if value is None:\n        return value\n    if isinstance(value, str) and _LOCAL_PATTERN.fullmatch(value):\n        return _parse_local_version(value)\n    msg = f\"local must be a valid version string, got {value!r}\"\n    raise InvalidVersion(msg)","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/packaging/version.py#L291-L327","documentation":"Raised by _validate_post() (version.py:303-309) when the post-release value passed to Version.from_parts() or Version.__replace__() is not a non-negative integer. Passing None is allowed (means no post-release). Strings, floats, negative ints, or bool-unlike values trigger this.","triggerScenarios":"Calling Version.from_parts(release=(1,), post=-1), Version.from_parts(release=(1,), post=1.5), or Version.from_parts(release=(1,), post='1').","commonSituations":"Passing a post-release value as a string from config, a negative number from a subtraction, or a float from division.","solutions":["Pass post as a non-negative int (0, 1, 2, ...).","Convert with int(value) and validate >= 0 before calling.","Pass None or omit the argument if there is no post-release segment."],"exampleFix":"// before\nVersion.from_parts(release=(1, 0), post='1')\n// after\nVersion.from_parts(release=(1, 0), post=1)","handlingStrategy":"type-guard","validationCode":"from packaging.version import Version, InvalidVersion\n\ndef safe_from_parts(*, release, post=None, **kwargs):\n    if post is not None and (not isinstance(post, int) or post < 0):\n        raise TypeError(f\"post must be a non-negative int, got {post!r}\")\n    return Version.from_parts(release=release, post=post, **kwargs)","typeGuard":"def is_valid_post(value) -> bool:\n    return value is None or (isinstance(value, int) and value >= 0)","tryCatchPattern":"from packaging.version import InvalidVersion\n\ntry:\n    v = Version.from_parts(release=(1,), post=post)\nexcept InvalidVersion as e:\n    if \"post must be\" in str(e):\n        logger.error(\"Invalid post value: %s\", post)\n    raise","preventionTips":["Pass post as a non-negative int","Convert string values with int() before calling","Pass None or omit to clear the post-release segment"],"tags":["version","post-release","packaging","pep440"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}