pypa/pip · error · SyntaxError

name expected: %s

Error message

name expected: %s

What it means

Raised by distlib's `parse_requirement` when the requirement string does not begin with a valid distribution name (the `IDENTIFIER` regex `^[\w\.-]+` fails to match the leading token). This is the very first check; if there's no leading identifier the requirement is rejected as malformed.

Source

Thrown at src/pip/_vendor/distlib/util.py:154

            remaining = remaining[m.end():]
            rhs, remaining = marker_and(remaining)
            lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs}
        return lhs, remaining

    return marker(marker_string)


def parse_requirement(req):
    """
    Parse a requirement passed in as a string. Return a Container
    whose attributes contain the various parts of the requirement.
    """
    remaining = req.strip()
    if not remaining or remaining.startswith('#'):
        return None
    m = IDENTIFIER.match(remaining)
    if not m:
        raise SyntaxError('name expected: %s' % remaining)
    distname = m.groups()[0]
    remaining = remaining[m.end():]
    extras = mark_expr = versions = uri = None
    if remaining and remaining[0] == '[':
        i = remaining.find(']', 1)
        if i < 0:
            raise SyntaxError('unterminated extra: %s' % remaining)
        s = remaining[1:i]
        remaining = remaining[i + 1:].lstrip()
        extras = []
        while s:
            m = IDENTIFIER.match(s)
            if not m:
                raise SyntaxError('malformed extra: %s' % s)
            extras.append(m.groups()[0])
            s = s[m.end():]
            if not s:
                break

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Ensure each requirement line starts with a valid distribution name (letters, digits, `_`, `-`, `.`).
  2. Remove stray lines or comment them out with `#`.
  3. Run `pip-compile`/`pip freeze` to regenerate a valid requirements file.

Example fix

# before
==2.28.0

# after
requests==2.28.0
Defensive patterns

Strategy: validation

Validate before calling

from packaging.requirements import Requirement, InvalidRequirement

def validate_requirement(line: str) -> None:
    try:
        Requirement(line)
    except InvalidRequirement as e:
        raise ValueError(f"Bad requirement: {e}") from e

Type guard

import re
IDENTIFIER = re.compile(r"^[A-Za-z_][\\w.-]*$")
def starts_with_valid_name(line: str) -> bool:
    line = line.strip()
    return bool(line) and bool(IDENTIFIER.match(line))

Try / catch

null

Prevention

When it happens

Trigger: `parse_requirement(req)` is invoked with a string that doesn't start with a valid name, e.g. `==1.0`, `@ http://...`, `# comment`, an empty string after strip is handled, but starting with a digit-only token is fine; fails for leading punctuation like `==` or `>=` or a stray `@`.

Common situations: Typing a version constraint without the package name; requirements files with a stray line; copy-paste that dropped the package name; malformed lines from tooling.

Related errors


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