pypa/pip · error · ValueError
limit must be non-negative
Error message
limit must be non-negative
What it means
Raised as ValueError by parse_tag (tags.py:274-275) when the limit keyword argument is not None and is negative. The limit caps how many tags a compressed tag set may expand to; a negative cap is meaningless, so it is rejected before any parsing begins.
Source
Thrown at src/pip/_vendor/packaging/tags.py:275
interpreter, ABI, or platform field (or any member of a compressed tag
set) is empty; or if the tag does not have exactly three components.
:raises TooManyTagsError: If **limit** is not ``None`` and the compressed tag
set would generate more than **limit** tags.
:raises ValueError: If **limit** is negative.
.. versionadded:: 26.1
The *validate_order* parameter.
.. versionadded:: 26.3
Raises :class:`InvalidTag` when an interpreter component is not an
identifier, a tag component is empty, or a tag does not have exactly
three components.
Added the *limit* parameter. Raises :class:`TooManyTagsError` if the compressed
tag set would generate more than *limit* tags.
"""
if limit is not None and limit < 0:
raise ValueError("limit must be non-negative")
component_parts = [component.split(".") for component in tag.split("-")]
for parts in component_parts:
if "" in parts:
component = ".".join(parts)
raise InvalidTag(f"Tag {tag!r} has an empty component: {component!r}")
if validate_order and parts != sorted(parts):
component = ".".join(parts)
raise UnsortedTagsError(
f"Tag component {component!r} is not in sorted order per PEP 425"
)
tag_count = 1
for parts in component_parts:
tag_count *= len(parts)
if limit is not None and tag_count > limit:
raise TooManyTagsError(View on GitHub (pinned to f399c37189)
Solutions
- Use limit=None to mean 'no cap' rather than a negative sentinel.
- Clamp the computed limit to max(0, value) before passing.
- Validate user-supplied limit: if value is None or value >= 0 pass through, else raise your own clear error.
- If a value like -1 is your 'unlimited' convention, translate it to None at the boundary.
Example fix
# before
parse_tag('py3-none-any', limit=budget - overshoot) # may be -1 -> ValueError
# after
limit = None if budget is None else max(0, budget - overshoot)
parse_tag('py3-none-any', limit=limit) Defensive patterns
Strategy: validation
Validate before calling
def clamp_limit(v):
return None if v is None else max(0, int(v)) Type guard
def is_valid_limit(v) -> bool:
return v is None or (isinstance(v, int) and v >= 0) Prevention
- Use None (not -1) to mean 'no limit'.
- Clamp computed limits with max(0, value).
- Translate your tool's 'unlimited' sentinel to None at the boundary.
When it happens
Trigger: parse_tag('py3-none-any', limit=-1); passing a limit computed from a subtraction that went negative (e.g. budget - overshoot); a CLI/config value parsed as a signed int where 0/-1 was used as 'unlimited' by mistake.
Common situations: A wheel-tag budget calculator that underflows; config defaulting to -1 meaning 'no limit' in another tool but fed to packaging's limit which expects None for unlimited; off-by-one in a tag-count estimator.
Related errors
- Tag {tag!r} has an empty component: {component!r}
- Tag component {component!r} is not in sorted order per PEP 4
- Compressed tag set would generate {tag_count} tags, exceedin
- Tag {tag!r} must have exactly three components
- Tag {tag!r} has an invalid interpreter: {interpreter!r}
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/8e31f161693c5de2.
Report an issue: GitHub.