nodejs/node · error · InvalidSpecifier
Invalid specifier: '{spec}'
Error message
Invalid specifier: '{spec}' What it means
packaging.specifiers.InvalidSpecifier raised by Specifier.__init__ when the operator+version regex finds no match in the supplied spec string. The regex expects one of the PEP 440 operator prefixes (==, !=, <=, >=, <, >, ~=, ===) followed by a version-like token; anything else is rejected before any normalization.
Source
Thrown at tools/gyp/pylib/packaging/specifiers.py:245
"===": "arbitrary",
}
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
"""Initialize a Specifier instance.
:param spec:
The string representation of a specifier which will be parsed and
normalized before use.
:param prereleases:
This tells the specifier if it should accept prerelease versions if
applicable or not. The default of ``None`` will autodetect it from the
given specifiers.
:raises InvalidSpecifier:
If the given specifier is invalid (i.e. bad syntax).
"""
match = self._regex.search(spec)
if not match:
raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
self._spec: Tuple[str, str] = (
match.group("operator").strip(),
match.group("version").strip(),
)
# Store whether or not this Specifier should accept prereleases
self._prereleases = prereleases
# https://github.com/python/mypy/pull/13475#pullrequestreview-1079784515
@property # type: ignore[override]
def prereleases(self) -> bool:
# If there is an explicit prereleases set for this, then we'll just
# blindly use that.
if self._prereleases is not None:
return self._prereleases
# Look at all of our specifiers and determine if they are inclusiveView on GitHub (pinned to 1b2de5e052)
Solutions
- Use SpecifierSet for multi-constraint strings like '>=1.0,<2.0'.
- Ensure the spec starts with a valid PEP 440 operator (==, !=, <=, >=, <, >, ~=, ===).
- Validate or sanitize user-supplied spec strings before constructing a Specifier, catching InvalidSpecifier to report the bad input.
Example fix
# before
spec = Specifier('>=1.0,<2.0')
# after
spec = SpecifierSet('>=1.0,<2.0') Defensive patterns
Strategy: validation
Validate before calling
import re
_spec_re = re.compile(r'^(==|!=|<=|>=|<|>|~=|===)\s*[^\s,]+')
def is_valid_specifier(s: str) -> bool:
return bool(_spec_re.match(s.strip())) Type guard
from packaging.specifiers import Specifier, InvalidSpecifier
def is_single_specifier(s: str) -> bool:
try:
Specifier(s)
return True
except InvalidSpecifier:
return False Try / catch
try:
spec = Specifier(user_input)
except InvalidSpecifier as e:
raise ValueError(f'Bad version constraint {user_input!r}: {e}') from e Prevention
- Use SpecifierSet for any string that may contain commas.
- Validate specifier strings from user/config input at the boundary.
- Reference PEP 440 operator syntax when documenting accepted input.
When it happens
Trigger: Constructing Specifier('1.0') (missing operator), Specifier('=>1.0') (wrong operator syntax), Specifier('==1.0,<2') (compound, which belongs to SpecifierSet not Specifier), or any spec with stray whitespace/punctuation that breaks the single-spec regex.
Common situations: Passing a requirements-style specifier directly to Specifier instead of SpecifierSet, typos in version constraints, or building specifiers from unvalidated user input / config files.
Related errors
- Invalid version: '{version}'
- invalid metadata
- unparsed
- invalid or unparsed metadata
- Cannot combine SpecifierSets with True and False prerelease
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/a4cfaf953be4d51e.
Report an issue: GitHub.