nodejs/node · error · ValueError
Cannot combine SpecifierSets with True and False prerelease
Error message
Cannot combine SpecifierSets with True and False prerelease overrides.
What it means
ValueError raised by SpecifierSet.__and__ (the & operator) when combining two SpecifierSets whose explicit prerelease overrides conflict - one has _prereleases True and the other False. The combine logic only resolves None-vs-value and equal-value cases; a True-vs-False contradiction cannot be merged deterministically, so it refuses.
Source
Thrown at tools/gyp/pylib/packaging/specifiers.py:828
>>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1')
<SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
"""
if isinstance(other, str):
other = SpecifierSet(other)
elif not isinstance(other, SpecifierSet):
return NotImplemented
specifier = SpecifierSet()
specifier._specs = frozenset(self._specs | other._specs)
if self._prereleases is None and other._prereleases is not None:
specifier._prereleases = other._prereleases
elif self._prereleases is not None and other._prereleases is None:
specifier._prereleases = self._prereleases
elif self._prereleases == other._prereleases:
specifier._prereleases = self._prereleases
else:
raise ValueError(
"Cannot combine SpecifierSets with True and False prerelease "
"overrides."
)
return specifier
def __eq__(self, other: object) -> bool:
"""Whether or not the two SpecifierSet-like objects are equal.
:param other: The other object to check against.
The value of :attr:`prereleases` is ignored.
>>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1")
True
>>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) ==
... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True))
TrueView on GitHub (pinned to 1b2de5e052)
Solutions
- Normalize both operands to the same prereleases value (or leave them as None for autodetection) before combining.
- Compute the intersection of one operand and then set .prereleases afterwards on the result.
- Catch ValueError and report which two SpecifierSets conflict so the user can reconcile them.
Example fix
# before
a = SpecifierSet('>=1.0', prereleases=True)
b = SpecifierSet('>=2.0', prereleases=False)
combined = a & b
# after
a = SpecifierSet('>=1.0')
b = SpecifierSet('>=2.0')
combined = a & b
combined.prereleases = True Defensive patterns
Strategy: validation
Validate before calling
def can_combine(a: SpecifierSet, b: SpecifierSet) -> bool:
if a._prereleases is None or b._prereleases is None:
return True
return a._prereleases == b._prereleases Try / catch
try:
combined = a & b
except ValueError as e:
if 'prerelease' in str(e):
b.prereleases = a.prereleases
combined = a & b Prevention
- Avoid setting .prereleases explicitly on operands you intend to merge.
- Centralize prerelease policy in one config location.
- Document which SpecifierSets carry an explicit override.
When it happens
Trigger: Computing SpecifierSet('>=1.0', prereleases=True) & SpecifierSet('>=1.0', prereleases=False) - i.e. intersecting two sets after one had .prereleases (or the prereleases= kwarg) set to True and the other to False.
Common situations: Merging requirement specifiers coming from different sources (e.g. user override vs. default config) where one side explicitly enables prereleases and the other explicitly disables them.
Related errors
- Invalid specifier: '{spec}'
- unable to parse identification
- invalid magic: {magic!r}
- unrecognized capacity ({self.capacity}) or encoding ({self.e
- unable to parse machine and section information
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/5a042f4fa59cf675.
Report an issue: GitHub.