{"id":"82282b6bcdc0e293","repo":"pypa/pip","slug":"invalid-group-name","errorCode":null,"errorMessage":"Invalid group name","messagePattern":"Invalid group name","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pkg_resources/__init__.py","lineNumber":2822,"sourceCode":"    @classmethod\n    def _parse_extras(cls, extras_spec):\n        if not extras_spec:\n            return ()\n        req = Requirement.parse('x' + extras_spec)\n        if req.specs:\n            raise ValueError\n        return req.extras\n\n    @classmethod\n    def parse_group(\n        cls,\n        group: str,\n        lines: _NestedStr,\n        dist: Distribution | None = None,\n    ):\n        \"\"\"Parse an entry point group\"\"\"\n        if not MODULE(group):\n            raise ValueError(\"Invalid group name\", group)\n        this: dict[str, Self] = {}\n        for line in yield_lines(lines):\n            ep = cls.parse(line, dist)\n            if ep.name in this:\n                raise ValueError(\"Duplicate entry point\", group, ep.name)\n            this[ep.name] = ep\n        return this\n\n    @classmethod\n    def parse_map(\n        cls,\n        data: str | Iterable[str] | dict[str, str | Iterable[str]],\n        dist: Distribution | None = None,\n    ):\n        \"\"\"Parse a map of entry point groups\"\"\"\n        _data: Iterable[tuple[str | None, str | Iterable[str]]]\n        if isinstance(data, dict):\n            _data = data.items()","sourceCodeStart":2804,"sourceCodeEnd":2840,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/pkg_resources/__init__.py#L2804-L2840","documentation":"pkg_resources raises this ValueError inside EntryPoint.parse_group when an entry point group name fails the MODULE regex (re.compile(r\"\\w+(\\.\\w+)*$\")). Entry point groups must be dotted Python identifiers (e.g. 'console_scripts', 'myapp.cli'), because the group string is used as a namespace key in entry_points.txt. Any non-identifier characters (spaces, hyphens, slashes) make the group invalid.","triggerScenarios":"Calling EntryPoint.parse_group(group, lines) or EntryPoint.parse_map(text) where group/header contains characters outside [A-Za-z0-9_] and dots; e.g. a malformed entry_points.txt with a section header like '[console scripts]' or '[my-group]'.","commonSituations":"Hand-edited entry_points.txt with a typo in the section header, a build tool emitting a group with hyphens, or a wheel whose metadata was generated incorrectly. Often surfaces during pip/pkg_resources working-set initialization.","solutions":["Open the offending entry_points.txt / METADATA and fix the [group] header so it is a dotted identifier (letters, digits, underscores, dots only).","Regenerate the wheel/sdist with a corrected setup.cfg / pyproject.toml entry_points section.","If you parse entry point data programmatically, validate the group with re.match(r'\\w+(\\.\\w+)*$', group) before calling parse_group."],"exampleFix":"# before (entry_points.txt)\n[console scripts]\nmytool = mypkg.cli:main\n\n# after\n[console_scripts]\nmytool = mypkg.cli:main","handlingStrategy":"validation","validationCode":"import re\n_GROUP_RE = re.compile(r\"\\w+(\\.\\w+)*$\")\ndef valid_group(group: str) -> bool:\n    return bool(_GROUP_RE(group))\n# only parse when valid:\nif valid_group(group):\n    ep_map = EntryPoint.parse_group(group, lines)","typeGuard":"def is_valid_entry_point_group(g: str) -> bool:\n    return isinstance(g, str) and bool(re.match(r\"\\w+(\\.\\w+)*$\", g))","tryCatchPattern":"try:\n    grp = EntryPoint.parse_group(group, lines)\nexcept ValueError as e:\n    if 'Invalid group name' in str(e):\n        raise ValueError(f'fix entry_points group {group!r}') from e\n    raise","preventionTips":["Always emit entry_points.txt via a build backend rather than hand-editing.","Lint group headers against the dotted-identifier regex in CI."],"tags":["python","pkg-resources","entry-points","metadata"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}