pypa/pip · error · ValueError
Duplicate group name
Error message
Duplicate group name
What it means
Raised by EntryPoint.parse_map when the same '[group]' section header appears more than once in the parsed data. Because the result is a dict keyed by group, a repeated header is ambiguous and pkg_resources rejects it with ValueError('Duplicate group name', group).
Source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:2851
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()
else:
_data = split_sections(data)
maps: dict[str, dict[str, Self]] = {}
for group, lines in _data:
if group is None:
if not lines:
continue
raise ValueError("Entry points must be listed in groups")
group = group.strip()
if group in maps:
raise ValueError("Duplicate group name", group)
maps[group] = cls.parse_group(group, lines, dist)
return maps
def _version_from_file(lines):
"""
Given an iterable of lines from a Metadata file, return
the value of the Version field, if present, or None otherwise.
"""
def is_version_line(line):
return line.lower().startswith('version:')
version_lines = filter(is_version_line, lines)
line = next(iter(version_lines), '')
_, _, value = line.partition(':')
return safe_version(value.strip()) or None
View on GitHub (pinned to d7d0d0a394)
Solutions
- Merge the entries of the duplicated group under a single '[group]' header.
- Regenerate the metadata from a single consolidated entry_points/ pyproject.toml source.
- If merging programmatically, accumulate lines per group into a dict before serializing instead of concatenating raw sections.
Example fix
# before [console_scripts] foo = a:main [console_scripts] bar = b:main # after [console_scripts] foo = a:main bar = b:main
Defensive patterns
Strategy: validation
Validate before calling
from configparser import ConfigParser
cp = ConfigParser()
cp.read_string(entry_points_txt)
# ConfigParser merges duplicate sections silently; to detect manually:
headers = [ln.strip() for ln in entry_points_txt.splitlines() if ln.strip().startswith('[')]
assert len(headers) == len(set(headers)), 'duplicate group section' Type guard
def has_unique_groups(text: str) -> bool:
seen = set()
for line in text.splitlines():
s = line.strip()
if s.startswith('[') and s.endswith(']'):
if s in seen:
return False
seen.add(s)
return True Try / catch
try:
EntryPoint.parse_map(data)
except ValueError as e:
if 'Duplicate group name' in str(e):
# merge sections, then retry
...
raise Prevention
- Merge entry-point sections from multiple packages before serializing.
- Use a dict {group: [lines]} when building maps in code.
When it happens
Trigger: entry_points.txt (or a dict passed to parse_map) contains two identical section headers, e.g. two '[console_scripts]' blocks; parse_map encounters the group already in 'maps'.
Common situations: Concatenating metadata from multiple sources, a packaging tool that appends a group instead of merging into the existing one, or manual editing that duplicated a header.
Related errors
- Duplicate entry point
- Invalid group name
- Entry points must be listed in groups
- Missing 'Version:' header and/or {} file at path: {}
- Entry point %r not found
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/1cd213457f6547b8.json.
Report an issue: GitHub.