pypa/pip · error · InstallationError

Will not install to the user site because it will lack…

Error message

Will not install to the user site because it will lack sys.path precedence to {dist.raw_name} in {dist.location}

What it means

Raised as InstallationError when pip is asked to install a package into the user site (via --user) inside a virtualenv, but a conflicting version of that package is already installed in the virtualenv's site-packages. In a virtualenv, the user site directory does not have sys.path precedence over site-packages, so the new user-site install would be shadowed by the old global install and silently fail to take effect. Rather than produce a broken install, pip refuses to proceed.

Solutions

  1. Remove the --user flag: inside a virtualenv, packages already install into the venv's site-packages, so --user is unnecessary and counterproductive.
  2. If you truly want a user-site install, exit the virtualenv (deactivate) first, then run the --user install against the system interpreter.
  3. Uninstall the existing copy from site-packages first (`pip uninstall <pkg>`), then reinstall without --user.
  4. Recreate or repair the virtualenv if site-packages is in an inconsistent state.

Example fix

// before
(venv) $ pip install --user requests

// after
(venv) $ pip install requests
Defensive patterns

Strategy: validation

Validate before calling

import sys, site

# Before running pip install --user, check if in a venv
venv = hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)
if venv:
    print('Inside a virtualenv: do NOT pass --user (it lacks path precedence).')
    # omit --user from your pip command
else:
    print('System Python: --user is acceptable.')

Type guard

import sys

def should_use_user_flag() -> bool:
    """Returns True only if --user is safe (not inside a venv)."""
    in_venv = hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix
    return not in_venv

Prevention

When it happens

Trigger: Running `pip install --user <pkg>` inside an active virtualenv where <pkg> is already present in the virtualenv's site-packages. The factory.get_dist_to_uninstall() method (factory.py:637) detects _use_user_site=True, dist.in_usersite=False, running_under_virtualenv()=True, and dist.in_site_packages=True, triggering the raise at line 662.

Common situations: Forgetting to activate the correct virtualenv before running pip install --user. Copying install commands (that include --user) from system-Python tutorials into a virtualenv workflow. Migrating from system pip to venv-based pip and reusing --user flags out of habit.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/a50d1a9c55f4ebc6. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/resolution/resolvelib/factory.py:662

        # be uninstalled, no matter it's in global or user site, because the
        # user site installation has precedence over global.
        if not self._use_user_site:
            return dist

        # We're installing into user site. Remove the user site installation.
        if dist.in_usersite:
            return dist

        # We're installing into user site, but the installed incompatible
        # package is in global site. We can't uninstall that, and would let
        # the new user installation to "shadow" it. But shadowing won't work
        # in virtual environments, so we error out.
        if running_under_virtualenv() and dist.in_site_packages:
            message = (
                f"Will not install to the user site because it will lack "
                f"sys.path precedence to {dist.raw_name} in {dist.location}"
            )
            raise InstallationError(message)
        return None

    def _report_requires_python_error(
        self, causes: Sequence[ConflictCause]
    ) -> UnsupportedPythonVersion:
        assert causes, "Requires-Python error reported with no cause"

        version = self._python_candidate.version

        if len(causes) == 1:
            specifier = str(causes[0].requirement.specifier)
            message = (
                f"Package {causes[0].parent.name!r} requires a different "
                f"Python: {version} not in {specifier!r}"
            )
            return UnsupportedPythonVersion(message)

        message = f"Packages require a different Python. {version} not in:"

View on GitHub (pinned to f399c37189)