pypa/pip · error · ValueError
Invalid section heading
Error message
Invalid section heading
What it means
Raised as ValueError in split_sections() at line 3538 when a line starts with '[' but does not end with ']'. This function parses INI-style sectioned metadata (entry_points.txt, requires.txt). A line like '[incomplete' (missing closing bracket) is an invalid section heading.
Solutions
- Ensure every section header line starts with '[' and ends with ']' with no trailing content.
- Check for stray '[' characters inside content lines (they should only appear in section headers).
- Regenerate entry_points.txt via reinstall or setup.py egg_info.
- Validate the metadata file with configparser before packaging.
Example fix
// before: entry_points.txt // [console_scripts // mycli = pkg:main // after // [console_scripts] // mycli = pkg:main
Defensive patterns
Strategy: validation
Validate before calling
import re
def has_valid_section_headers(text: str) -> bool:
for line in text.strip().splitlines():
s = line.strip()
if s.startswith('['):
if not s.endswith(']'):
return False
return True Type guard
def is_valid_section_line(line: str) -> bool:
s = line.strip()
if s.startswith('['):
return s.endswith(']')
return True
Try / catch
from pkg_resources import split_sections
try:
sections = list(split_sections(text))
except ValueError:
# fix malformed headers and retry, or log the error
text = fix_section_headers(text)
sections = list(split_sections(text))
Prevention
- Validate metadata section headers with configparser before packaging.
- Ensure every '[' has a matching ']' on the same line.
- Regenerate entry_points.txt via reinstall if hand-edited.
When it happens
Trigger: Parsing metadata text (entry_points.txt, requires.txt) where a line begins with '[' but lacks a matching closing ']'. This can happen in parse_map -> split_sections, or any direct call to split_sections with malformed section headers.
Common situations: Hand-edited entry_points.txt with a truncated section header; encoding issues that corrupt the ']'; copy-paste errors; automated tools that generate malformed section names containing brackets mid-line.
Related errors
- Entry points must be listed in groups
- Error parsing entry points for
- Badly formatted data
- Duplicate entry point
- EntryPoint must be in 'name=module:attrs [extras]' format
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/81ef9d79f6b8b66a.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:3538
def split_sections(s: _NestedStr) -> Iterator[tuple[str | None, list[str]]]:
"""Split a string or iterable thereof into (section, content) pairs
Each ``section`` is a stripped version of the section header ("[section]")
and each ``content`` is a list of stripped lines excluding blank lines and
comment-only lines. If there are any such lines before the first section
header, they're returned in a first ``section`` of ``None``.
"""
section = None
content = []
for line in yield_lines(s):
if line.startswith("["):
if line.endswith("]"):
if section or content:
yield section, content
section = line[1:-1].strip()
content = []
else:
raise ValueError("Invalid section heading", line)
else:
content.append(line)
# wrap up last segment
yield section, content
def _mkstemp(*args, **kw):
old_open = os.open
try:
# temporarily bypass sandboxing
os.open = os_open
return tempfile.mkstemp(*args, **kw)
finally:
# and then put it back
os.open = old_open
View on GitHub (pinned to f399c37189)