pypa/pip · error · RequirementsFileParseError
Invalid requirement: {line}\n{e.msg}
Error message
Invalid requirement: {line}\n{e.msg} What it means
RequirementsFileParseError raised while parsing a single line of a requirements/constraints file: the line could not be split into args + options by pip's optparse-based line parser (OptionParsingError). The offending line is echoed along with the parser's message so the user can locate the typo.
Source
Thrown at src/pip/_internal/req/req_file.py:415
req_path, nested_constraint, [new_parsed_files, *parsed_files_stack]
)
else:
yield line
def _parse_file(
self, filename: str, constraint: bool
) -> Generator[ParsedLine, None, None]:
_, content = get_file_content(filename, self._session, constraint=constraint)
lines_enum = preprocess(content)
for line_number, line in lines_enum:
try:
args_str, opts = self._line_parser(line)
except OptionParsingError as e:
# add offending line
msg = f"Invalid requirement: {line}\n{e.msg}"
raise RequirementsFileParseError(msg)
yield ParsedLine(
filename,
line_number,
args_str,
opts,
constraint,
)
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:View on GitHub (pinned to d7d0d0a394)
Solutions
- Read {line} and {e.msg} from the error: they pinpoint the bad line and the parser complaint.
- Cross-check the option name against pip's supported requirement-line options (--index-url, --extra-index-url, --find-links, --hash, etc.).
- Quote values that contain spaces and ensure each '--opt=value' or '--opt value' pair is complete.
- Remove the offending option or move it to the CLI invocation if it isn't valid in a requirements file.
Example fix
# before — requirements.txt requests --find-lins https://example.com # after requests --find-links https://example.com
Defensive patterns
Strategy: validation
Validate before calling
from pip._internal.req.req_file import get_line_parser, OptionParsingError
def validate_line(line: str, finder=None) -> bool:
try:
get_line_parser(finder)(line)
return True
except OptionParsingError as e:
print(f'bad line: {line!r} -> {e.msg}')
return False Type guard
def is_valid_requirement_line(line: str) -> bool:
return validate_line(line) Try / catch
from pip._internal.req.req_file import get_line_parser, OptionParsingError
for line in open('requirements.txt'):
line = line.strip()
if not line or line.startswith('#'):
continue
try:
get_line_parser(None)(line)
except OptionParsingError as e:
print(f'fix line: {line} ({e.msg})'); raise SystemExit(1) Prevention
- Use pip's own parser to lint requirements files in CI.
- Cross-check option names against 'pip install --help'.
- Prefer '--opt=value' to avoid optparse ambiguities.
When it happens
Trigger: Running 'pip install -r requirements.txt' where a line uses an unknown option flag (e.g. '--foo'), a malformed option (missing value after '--index-url'), or text that optparse rejects. Anything in the options portion after the first '--'-prefixed token gets parsed by optparse.
Common situations: Typos in option names ('--find-links' misspelled); copy-pasting a shell-style '--index-url=http://...' that optparse still accepts but a missing '=' elsewhere breaks; environment-specific options from a teammate's machine; trailing option tokens a user thought were part of the package name.
Related errors
- Could not split options: {options_str}
- {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/158de07c441fa226.json.
Report an issue: GitHub.