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
- Locate the line in {options_str} (the error shows the offending substring) and balance all quotes.
- Use '--opt=value' form (no spaces) to avoid shlex pitfalls for URLs with special characters.
- Replace smart/curly quotes with straight ASCII quotes.
- 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
- Always close quotes on requirement lines with URLs.
- Use '--opt=value' (no spaces) to sidestep shlex entirely.
- Strip smart quotes when pasting from rich text.
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
- Invalid requirement: {line}\n{e.msg}
- {req_path} recursively references itself in {filename}{tail}
- Could not open {kind} file: {exc}
- Invalid section heading
- <dynamic: PEP723 exception message (exc.msg)>
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/1d0df2b26ef77a09.json.
Report an issue: GitHub.