pypa/pip · error · OptionParsingError

Could not split options: {options_str}

Error message

Could not split options: {options_str}

What it means

OptionParsingError raised inside get_line_parser when shlex.split(options_str) fails on the options portion of a requirements line. shlex raises ValueError on unbalanced quotes or other shell-lex errors, and pip re-raises as OptionParsingError which the file parser then turns into a RequirementsFileParseError. The full options substring is shown.

Source

Thrown at src/pip/_internal/req/req_file.py:442


def get_line_parser(finder: PackageFinder | None) -> LineParser:
    def parse_line(line: str) -> tuple[str, Values]:
        # Build new parser for each line since it accumulates appendable
        # options.
        parser = build_parser()
        defaults = parser.get_default_values()
        defaults.index_url = None
        if finder:
            defaults.format_control = finder.format_control
            defaults.release_control = finder.release_control

        args_str, options_str = break_args_options(line)

        try:
            options = shlex.split(options_str)
        except ValueError as e:
            raise OptionParsingError(f"Could not split options: {options_str}") from e

        opts, _ = parser.parse_args(options, defaults)

        return args_str, opts

    return parse_line


def break_args_options(line: str) -> tuple[str, str]:
    """Break up the line into an args and options string.  We only want to shlex
    (and then optparse) the options, not the args.  args can contain markers
    which are corrupted by shlex.
    """
    tokens = line.split(" ")
    args = []
    options = tokens[:]
    for token in tokens:
        if token.startswith(("-", "--")):

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Locate the line in {options_str} (the error shows the offending substring) and balance all quotes.
  2. Use '--opt=value' form (no spaces) to avoid shlex pitfalls for URLs with special characters.
  3. Replace smart/curly quotes with straight ASCII quotes.
  4. Re-run pip to confirm parsing succeeds.

Example fix

# before
requests --find-links "https://example.com/wheels

# after
requests --find-links=https://example.com/wheels
Defensive patterns

Strategy: validation

Validate before calling

import shlex
def options_split_ok(options_str: str) -> bool:
    try:
        shlex.split(options_str)
        return True
    except ValueError:
        return False

Type guard

def is_shlex_safe(options_str: str) -> bool:
    return options_split_ok(options_str)

Try / catch

import shlex
try:
    shlex.split(options_str)
except ValueError as e:
    print(f'unbalanced quotes in: {options_str}'); raise
run_pip(['install', '-r', 'requirements.txt'])

Prevention

When it happens

Trigger: A requirements line whose option part has an unmatched quote, e.g. 'pkg --find-links "https://example.com' (missing closing quote), or an unescaped special character that shlex cannot tokenize. Triggered by 'pip install -r <file>'.

Common situations: Hand-editing a requirements file and dropping a closing quote; URL with a stray '"'; copy-pasting from a rich-text source that converted quotes to smart quotes; whitespace inside an unquoted value.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/1d0df2b26ef77a09.json. Report an issue: GitHub.