pypa/pip · error · CommandError

--all-releases / --only-final option requires 1 argument.

Error message

--all-releases / --only-final option requires 1 argument.

What it means

Raised as a CommandError by ReleaseControl.handle_mutual_excludes when the value passed to --all-releases or --only-final starts with a '-', i.e. it looks like the next CLI flag rather than a real argument. These options each require exactly one argument (a package name, ':all:', ':none:', or a comma-separated list), so a flag-like value means the option was supplied without its argument.

Solutions

  1. Supply an explicit argument to the option: a package name, ':all:', ':none:', or comma-separated names.
  2. Reorder arguments so the option's value is not another flag, e.g. 'pip install --all-releases :all: pkg'.
  3. Check pip.conf / requirements files for an --all-releases/--only-final entry that omits its value.

Example fix

# before
pip install --all-releases --only-final pkg

# after
pip install --all-releases :all: pkg
Defensive patterns

Strategy: validation

Validate before calling

def valid_release_arg(value: str) -> bool:
    # --all-releases / --only-final require one non-flag argument
    return not value.startswith("-")

# assert valid_release_arg(":all:")
# assert not valid_release_arg("--only-final")

Prevention

When it happens

Trigger: Running pip install with '--all-releases' immediately followed by another option (e.g. '--all-releases --only-final pkg'), or argparse forwarding a '-'-prefixed token. handle_mutual_excludes sees value.startswith('-') and aborts before canonicalizing.

Common situations: Treating the new release-control options as boolean flags; misordered CLI arguments where the option's argument is missing; script-generated command lines that drop the value.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/models/release_control.py:33

    only_final: set[str] = field(default_factory=set)
    _order: list[tuple[str, str]] = field(
        init=False, default_factory=list, compare=False, repr=False
    )

    def handle_mutual_excludes(
        self, value: str, target: set[str], other: set[str], attr_name: str
    ) -> None:
        """Parse and apply release control option value.

        Processes comma-separated package names or special values `:all:` and `:none:`.

        When adding packages to target, they're removed from other to maintain mutual
        exclusivity between all_releases and only_final. All operations are tracked in
        order so that the original command-line argument sequence can be reconstructed
        when passing options to build subprocesses.
        """
        if value.startswith("-"):
            raise CommandError(
                "--all-releases / --only-final option requires 1 argument."
            )
        new = value.split(",")
        while ":all:" in new:
            other.clear()
            target.clear()
            target.add(":all:")
            # Track :all: in order
            self._order.append((attr_name, ":all:"))
            del new[: new.index(":all:") + 1]
            # Without a none, we want to discard everything as :all: covers it
            if ":none:" not in new:
                return
        for name in new:
            if name == ":none:":
                target.clear()
                # Track :none: in order
                self._order.append((attr_name, ":none:"))

View on GitHub (pinned to f399c37189)