pypa/pip · error · PylockSelectError

Multiple packages with the name

Error message

Multiple packages with the name {package.name!r} are selected at packages[{package_index}] and packages[{selected_packages_by_name[package.name][0]}]

What it means

PylockSelectError raised by Pylock.select when two distinct package entries share the same name and both are selected (their markers both match the environment). PEP 751 forbids installing two versions of one distribution simultaneously, so ambiguity is rejected and both array indices are reported.

Solutions

  1. Inspect packages[index] and packages[other_index] named in the message; they share a name.
  2. Tighten each entry's 'marker' so only one can match any given environment (e.g. platform-specific splits), OR delete the duplicate entry.
  3. If one is a direct (VCS/directory) source and the other is a wheel for the same project, merge them into a single package entry with the appropriate source fields.
  4. Regenerate the lock from a clean dependency set to avoid duplicates.

Example fix

# before: two entries both named "requests", both markers match Linux
[[packages]]
name = "requests"
version = "2.31.0"
marker = "platform_system == 'Linux'"
[[packages]]
name = "requests"
version = "2.31.0"
marker = "platform_machine == 'x86_64'"

# after: merge into one entry, or make markers mutually exclusive
[[packages]]
name = "requests"
version = "2.31.0"
marker = "platform_system == 'Linux' and platform_machine == 'x86_64'"
Defensive patterns

Strategy: validation

Validate before calling

from packaging.markers import default_environment

def no_duplicate_selected_names(pylock, environment=None) -> bool:
    env = environment or default_environment()
    seen = {}
    for i, p in enumerate(pylock.packages):
        if p.marker and not p.marker.evaluate(env, context='lock_file'):
            continue
        if p.name in seen:
            return False
        seen[p.name] = i
    return True

assert no_duplicate_selected_names(pylock, env)

Type guard

null

Try / catch

from packaging.pylock import PylockSelectError
try:
    list(pylock.select(environment=env))
except PylockSelectError as e:
    # message names both indices; make their markers mutually exclusive or merge
    report(e)

Prevention

When it happens

Trigger: In the select() loop, selected_packages_by_name tracks already-selected package names; when a later packages[j] has the same name as an earlier packages[i] and both pass their markers, the check 'package.name in selected_packages_by_name' fires, reporting packages[j] and packages[i].

Common situations: Lock accidentally lists the same distribution twice (e.g. once as a wheel package and once as a VCS source); two entries that differ only by marker but both markers match the current environment; a merge of two lock files creating duplicates.

Related errors


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

Appendix: source

Thrown at src/pip/_vendor/packaging/pylock.py:874

            if package.marker and not package.marker.evaluate(env, context="lock_file"):
                continue

            # #. If :ref:`pylock-packages-requires-python` is specified, check if it is
            #    satisfied; an error MUST be raised if it isn't.
            if package.requires_python and not package.requires_python.contains(
                env_python_full_version,
            ):
                raise PylockSelectError(
                    f"python_full_version {env_python_full_version!r} "
                    f"in provided environment does not satisfy the Python version "
                    f"requirement {str(package.requires_python)!r} for package "
                    f"{package.name!r} at packages[{package_index}]"
                )

            # #. Check that no other conflicting instance of the package has been slated
            #    to be installed; an error about the ambiguity MUST be raised otherwise.
            if package.name in selected_packages_by_name:
                raise PylockSelectError(
                    f"Multiple packages with the name {package.name!r} are "
                    f"selected at packages[{package_index}] and "
                    f"packages[{selected_packages_by_name[package.name][0]}]"
                )

            # #. Check that the source of the package is specified appropriately (i.e.
            #    there are no conflicting sources in the package entry);
            #    an error MUST be raised if any issues are found.
            # Covered by lock.validate() which is a precondition for this method.

            # #. Add the package to the set of packages to install.
            selected_packages_by_name[package.name] = (package_index, package)

        # #. For each package to be installed:
        for package_index, package in selected_packages_by_name.values():
            # - If :ref:`pylock-packages-vcs` is set:
            if package.vcs is not None:
                yield package, package.vcs

View on GitHub (pinned to f399c37189)