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

  1. Check the offending line against pip's supported requirements-file options
  2. Look for typos in option flags (e.g. --fnd-links vs --find-links, --index-ur vs --index-url)
  3. Verify the option is valid in the context (some options only apply to requirement lines, not option-only lines)
  4. 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

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


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