pypa/pip · error · VersionConflict
{self.dist} is installed but {self.req} is required by {self
Error message
{self.dist} is installed but {self.req} is required by {self.required_by} What it means
Raised as ContextualVersionConflict during WorkingSet.resolve() when the best-matching distribution found for a transitive dependency conflicts with that dependency's own requirement, and there is at least one known requirer. It is produced by calling VersionConflict(dist, req).with_context(dependent_req), which appends the set of requirers and switches the message template to include 'by {self.required_by}'. This surfaces multi-level dependency conflicts with attribution.
Source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:934
if dist is None:
env = Environment(self.entries)
else:
# Use an empty environment and workingset to avoid
# any further conflicts with the conflicting
# distribution
env = Environment([])
ws = WorkingSet([])
dist = best[req.key] = env.best_match(
req, ws, installer, replace_conflicting=replace_conflicting
)
if dist is None:
requirers = required_by.get(req, None)
raise DistributionNotFound(req, requirers)
to_activate.append(dist)
if dist not in req:
# Oops, the "best" so far conflicts with a dependency
dependent_req = required_by[req]
raise VersionConflict(dist, req).with_context(dependent_req)
return dist
@overload
def find_plugins(
self,
plugin_env: Environment,
full_env: Environment | None,
installer: _InstallerTypeT[_DistributionT],
fallback: bool = True,
) -> tuple[list[_DistributionT], dict[Distribution, Exception]]: ...
@overload
def find_plugins(
self,
plugin_env: Environment,
full_env: Environment | None = None,
*,
installer: _InstallerTypeT[_DistributionT],
fallback: bool = True,View on GitHub (pinned to f399c37189)
Solutions
- Read the 'required_by' field to identify which packages impose the conflicting constraints, then align them.
- Upgrade or downgrade the contested dependency to a version satisfying all requirers, or relax one package's pin.
- Use pip's resolver output (pip install with --dry-run) to find a compatible set, then pin that version.
Example fix
// before # app pins lib==1.0, plugin needs lib>=2.0 pkg_resources.require(['app', 'plugin']) // after # upgrade lib to satisfy both, or drop the conflicting plugin pip install 'lib>=2.0' pkg_resources.require(['app', 'plugin'])
Defensive patterns
Strategy: try-catch
Try / catch
try:
pkg_resources.require(deps)
except ContextualVersionConflict as e:
print(e.report())
print('Required by:', e.required_by) Prevention
- Pin all transitive dependencies in a lock file to avoid conflicting ranges.
- Use pip's resolver at install time to surface conflicts early.
When it happens
Trigger: During resolve(), package A requires 'lib>=2.0' and package B requires 'lib<2.0'; the resolver picks a lib version and one side conflicts, raising ContextualVersionConflict naming the installed dist, the unsatisfied req, and the dependent (requirer).
Common situations: Conflicting transitive version constraints between two installed packages; a plugin requiring a newer core library than the application pins; incompatible dependency pins across a monorepo.
Related errors
- {self.dist} is installed but {self.req} is required
- Error decoding metadata for {self._wheel_name}: {e} in {name
- Wheel '{name}' located at {location} is invalid.
- {name} has an invalid wheel, {e}
- None {metadata_name} metadata found for distribution: {dist}
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/724cbd262147282f.
Report an issue: GitHub.