{"id":"feabb7ae47de96f6","repo":"pypa/pip","slug":"name-expected-s","errorCode":null,"errorMessage":"name expected: %s","messagePattern":"name expected: (.+?)","errorType":"validation","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/distlib/util.py","lineNumber":154,"sourceCode":"            remaining = remaining[m.end():]\n            rhs, remaining = marker_and(remaining)\n            lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs}\n        return lhs, remaining\n\n    return marker(marker_string)\n\n\ndef parse_requirement(req):\n    \"\"\"\n    Parse a requirement passed in as a string. Return a Container\n    whose attributes contain the various parts of the requirement.\n    \"\"\"\n    remaining = req.strip()\n    if not remaining or remaining.startswith('#'):\n        return None\n    m = IDENTIFIER.match(remaining)\n    if not m:\n        raise SyntaxError('name expected: %s' % remaining)\n    distname = m.groups()[0]\n    remaining = remaining[m.end():]\n    extras = mark_expr = versions = uri = None\n    if remaining and remaining[0] == '[':\n        i = remaining.find(']', 1)\n        if i < 0:\n            raise SyntaxError('unterminated extra: %s' % remaining)\n        s = remaining[1:i]\n        remaining = remaining[i + 1:].lstrip()\n        extras = []\n        while s:\n            m = IDENTIFIER.match(s)\n            if not m:\n                raise SyntaxError('malformed extra: %s' % s)\n            extras.append(m.groups()[0])\n            s = s[m.end():]\n            if not s:\n                break","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/distlib/util.py#L136-L172","documentation":"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.","triggerScenarios":"`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 `@`.","commonSituations":"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.","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."],"exampleFix":"# before\n==2.28.0\n\n# after\nrequests==2.28.0","handlingStrategy":"validation","validationCode":"from packaging.requirements import Requirement, InvalidRequirement\n\ndef validate_requirement(line: str) -> None:\n    try:\n        Requirement(line)\n    except InvalidRequirement as e:\n        raise ValueError(f\"Bad requirement: {e}\") from e","typeGuard":"import re\nIDENTIFIER = re.compile(r\"^[A-Za-z_][\\\\w.-]*$\")\ndef starts_with_valid_name(line: str) -> bool:\n    line = line.strip()\n    return bool(line) and bool(IDENTIFIER.match(line))","tryCatchPattern":"null","preventionTips":["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."],"tags":["distlib","requirements-parsing","pep508"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}