pypa/pip · error · CommandError

Options --outdated and --uptodate cannot be combined.

Error message

Options --outdated and --uptodate cannot be combined.

What it means

Raised by pip list's run() when both --outdated and --uptodate are passed simultaneously. These flags are logically contradictory: --outdated lists packages with a newer version available, while --uptodate lists packages already at the newest version. Since no package can be in both states, pip rejects the combination rather than returning an empty list.

Solutions

  1. Use only one of the two flags depending on your goal: `pip list --outdated` to see upgradable packages, or `pip list --uptodate` to see current ones.
  2. If building the command dynamically, ensure the two flags are mutually exclusive in your flag-assembly logic.
  3. Check pip.conf and PIP_* environment variables for both options being set.

Example fix

# before
pip list --outdated --uptodate
# after
pip list --outdated
Defensive patterns

Strategy: validation

Validate before calling

def build_pip_list_cmd(outdated: bool, uptodate: bool) -> list[str]:
    if outdated and uptodate:
        raise ValueError('--outdated and --uptodate are mutually exclusive')
    cmd = ['pip', 'list']
    if outdated:
        cmd.append('--outdated')
    if uptodate:
        cmd.append('--uptodate')
    return cmd

Prevention

When it happens

Trigger: Invoking `pip list --outdated --uptodate`, or setting both options via a config file / environment variables (PIP_OUTDATED and PIPELINE aliases), or via a shell alias that appends both flags.

Common situations: Copy-pasting a pip list command from documentation without removing the irrelevant flag; scripts that build flags dynamically and accidentally concatenate both; stale shell aliases.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/commands/list.py:177

        # Pass allow_yanked=False to ignore yanked versions.
        selection_prefs = SelectionPreferences(
            allow_yanked=False,
            release_control=options.release_control,
            format_control=options.format_control,
            prefer_binary=options.prefer_binary,
        )

        return PackageFinder.create(
            link_collector=link_collector,
            selection_prefs=selection_prefs,
            uploaded_prior_to=options.uploaded_prior_to,
        )

    def run(self, options: Values, args: list[str]) -> int:
        cmdoptions.check_release_control_exclusive(options)

        if options.outdated and options.uptodate:
            raise CommandError("Options --outdated and --uptodate cannot be combined.")

        if options.outdated and options.list_format == "freeze":
            raise CommandError(
                "List format 'freeze' cannot be used with the --outdated option."
            )

        cmdoptions.check_list_path_option(options)

        packages: _ProcessedDists = [
            cast("_DistWithLatestInfo", d)
            for d in get_environment(options.path).iter_installed_distributions(
                local_only=options.local,
                user_only=options.user,
                editables_only=options.editable,
                include_editables=options.include_editable,
                skip=set(stdlib_pkgs),
            )
        ]

View on GitHub (pinned to f399c37189)