pypa/pip · error · InvalidVersion
post must be non-negative integer, got
Error message
post must be non-negative integer, got {value} What it means
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.
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.
Example fix
// before Version.from_parts(release=(1, 0), post='1') // after Version.from_parts(release=(1, 0), post=1)
Defensive patterns
Strategy: type-guard
Validate before calling
from packaging.version import Version, InvalidVersion
def safe_from_parts(*, release, post=None, **kwargs):
if post is not None and (not isinstance(post, int) or post < 0):
raise TypeError(f"post must be a non-negative int, got {post!r}")
return Version.from_parts(release=release, post=post, **kwargs) Type guard
def is_valid_post(value) -> bool:
return value is None or (isinstance(value, int) and value >= 0) Try / catch
from packaging.version import InvalidVersion
try:
v = Version.from_parts(release=(1,), post=post)
except InvalidVersion as e:
if "post must be" in str(e):
logger.error("Invalid post value: %s", post)
raise Prevention
- Pass post as a non-negative int
- Convert string values with int() before calling
- Pass None or omit to clear the post-release segment
When it happens
Trigger: Calling Version.from_parts(release=(1,), post=-1), Version.from_parts(release=(1,), post=1.5), or Version.from_parts(release=(1,), post='1').
Common situations: Passing a post-release value as a string from config, a negative number from a subtraction, or a float from division.
Related errors
- dev must be non-negative integer, got
- epoch must be non-negative integer, got
- Invalid sdist filename (invalid version)
- Invalid version
- Invalid wheel filename (invalid version)
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/efd9347ba1d420e6.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/version.py:309
if (
isinstance(letter, str)
and (normalized := normalize_pre(letter)) in {"a", "b", "rc"}
and isinstance(number, int)
and number >= 0
):
# type checkers can't infer the Literal type here on letter
return (normalized, number) # type: ignore[return-value]
msg = f"pre must be a tuple of ('a'|'b'|'rc', non-negative int), got {value}"
raise InvalidVersion(msg)
def _validate_post(value: object, /) -> tuple[Literal["post"], int] | None:
if value is None:
return value
if isinstance(value, int) and value >= 0:
return ("post", value)
msg = f"post must be non-negative integer, got {value}"
raise InvalidVersion(msg)
def _validate_dev(value: object, /) -> tuple[Literal["dev"], int] | None:
if value is None:
return value
if isinstance(value, int) and value >= 0:
return ("dev", value)
msg = f"dev must be non-negative integer, got {value}"
raise InvalidVersion(msg)
def _validate_local(value: object, /) -> LocalType | None:
if value is None:
return value
if isinstance(value, str) and _LOCAL_PATTERN.fullmatch(value):
return _parse_local_version(value)
msg = f"local must be a valid version string, got {value!r}"
raise InvalidVersion(msg)View on GitHub (pinned to f399c37189)