pypa/pip · error · ValueError

Invalid group name

Error message

Invalid group name

What it means

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.

Source

Thrown at src/pip/_vendor/pkg_resources/__init__.py:2822

    @classmethod
    def _parse_extras(cls, extras_spec):
        if not extras_spec:
            return ()
        req = Requirement.parse('x' + extras_spec)
        if req.specs:
            raise ValueError
        return req.extras

    @classmethod
    def parse_group(
        cls,
        group: str,
        lines: _NestedStr,
        dist: Distribution | None = None,
    ):
        """Parse an entry point group"""
        if not MODULE(group):
            raise ValueError("Invalid group name", group)
        this: dict[str, Self] = {}
        for line in yield_lines(lines):
            ep = cls.parse(line, dist)
            if ep.name in this:
                raise ValueError("Duplicate entry point", group, ep.name)
            this[ep.name] = ep
        return this

    @classmethod
    def parse_map(
        cls,
        data: str | Iterable[str] | dict[str, str | Iterable[str]],
        dist: Distribution | None = None,
    ):
        """Parse a map of entry point groups"""
        _data: Iterable[tuple[str | None, str | Iterable[str]]]
        if isinstance(data, dict):
            _data = data.items()

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Open the offending entry_points.txt / METADATA and fix the [group] header so it is a dotted identifier (letters, digits, underscores, dots only).
  2. Regenerate the wheel/sdist with a corrected setup.cfg / pyproject.toml entry_points section.
  3. If you parse entry point data programmatically, validate the group with re.match(r'\w+(\.\w+)*$', group) before calling parse_group.

Example fix

# before (entry_points.txt)
[console scripts]
mytool = mypkg.cli:main

# after
[console_scripts]
mytool = mypkg.cli:main
Defensive patterns

Strategy: validation

Validate before calling

import re
_GROUP_RE = re.compile(r"\w+(\.\w+)*$")
def valid_group(group: str) -> bool:
    return bool(_GROUP_RE(group))
# only parse when valid:
if valid_group(group):
    ep_map = EntryPoint.parse_group(group, lines)

Type guard

def is_valid_entry_point_group(g: str) -> bool:
    return isinstance(g, str) and bool(re.match(r"\w+(\.\w+)*$", g))

Try / catch

try:
    grp = EntryPoint.parse_group(group, lines)
except ValueError as e:
    if 'Invalid group name' in str(e):
        raise ValueError(f'fix entry_points group {group!r}') from e
    raise

Prevention

When it happens

Trigger: 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]'.

Common situations: 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.

Related errors


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