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:
breakView on GitHub (pinned to d7d0d0a394)
Solutions
- Ensure each requirement line starts with a valid distribution name (letters, digits, `_`, `-`, `.`).
- Remove stray lines or comment them out with `#`.
- 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
- Every requirement line must begin with a valid distribution name.
- Comment out or remove stray lines (`#`).
- Validate requirements files with `packaging.requirements.Requirement` in a pre-commit hook.
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
- error in string literal: %s
- unterminated string: %s
- unterminated parenthesis: %s
- invalid URI: %s
- Invalid URL: %s
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/feabb7ae47de96f6.json.
Report an issue: GitHub.