pypa/pip · error · RequirementsFileParseError
Invalid requirement: {line} {e.msg}
Error message
Invalid requirement: {line}
{e.msg} What it means
While parsing a line in a requirements file, the per-line option parser (optparse) raised an OptionParsingError. This happens when the line contains options that pip does not recognize or that are malformed. The error wraps the offending line text and the parser's error message into a RequirementsFileParseError.
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 f399c37189)
Solutions
- Check the offending line against pip's supported requirements-file options
- Look for typos in option flags (e.g. --fnd-links vs --find-links, --index-ur vs --index-url)
- Verify the option is valid in the context (some options only apply to requirement lines, not option-only lines)
- Upgrade pip if the option was recently added and your version is old
Example fix
# before — requirements.txt requests --fnd-links https://example.com/wheels/ # after requests --find-links https://example.com/wheels/
Defensive patterns
Strategy: try-catch
Validate before calling
from pip._internal.req.req_file import build_parser, break_args_options
import shlex
def validate_req_line(line: str) -> bool:
try:
args_str, options_str = break_args_options(line)
options = shlex.split(options_str)
parser = build_parser()
parser.parse_args(options, parser.get_default_values())
return True
except Exception:
return False Type guard
from pip._internal.req.req_file import build_parser, break_args_options, OptionParsingError
import shlex
def is_valid_req_file_line(line: str) -> bool:
"""Type guard: True if the line parses without OptionParsingError."""
try:
args_str, options_str = break_args_options(line)
parser = build_parser()
parser.parse_args(shlex.split(options_str), parser.get_default_values())
return True
except Exception:
return False Try / catch
from pip._internal.exceptions import RequirementsFileParseError
from pip._internal.req.req_file import parse_requirements
try:
list(parse_requirements("requirements.txt", session))
except RequirementsFileParseError as e:
if "Invalid requirement" in str(e):
print(f"Fix the malformed line: {e}")
else:
raise Prevention
- Check option names against pip's supported list in requirements files
- Watch for typos like --fnd-links instead of --find-links
- Validate requirements files with a linter or dry-run parse before CI
When it happens
Trigger: A requirements file line with an unrecognized option flag, e.g. 'requests --fnd-links https://example.com' (typo for --find-links), or an option used in a context where it is not allowed. The OptionParsingError is caught in _parse_file and re-raised.
Common situations: Typo in option names. Using an option not in the SUPPORTED_OPTIONS list for that context. Deprecated options removed in newer pip versions. Copy-paste from documentation with formatting artifacts.
Related errors
- {req_path} recursively references itself in {filename}{tail}
- Could not split options: {options_str}
- Options --outdated and --uptodate cannot be combined.
- List format 'freeze' cannot be used with the --outdated opti
- Configuration file could not be loaded.\n{error}\n
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/c72263d05ece910e.
Report an issue: GitHub.