pypa/pip · error · ValueError
Invalid section heading
Error message
Invalid section heading
What it means
Raised as ValueError from split_sections when a line begins with '[' but does not end with ']'. split_sections parses INI-like section headers ('[name]'); a line that opens a bracket without closing it is treated as a malformed section heading.
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 d7d0d0a394)
Solutions
- Fix the malformed header so it is '[group]' with matching brackets.
- If the line is genuine content starting with '[', escape or restructure it so it does not look like a section.
- Validate the file as valid INI (configparser) before feeding it to split_sections.
Example fix
# before (entry_points.txt) [console_scripts foo = mod:fn # after [console_scripts] foo = mod:fn
Defensive patterns
Strategy: validation
Validate before calling
def balanced_section(line: str) -> bool:
s = line.strip()
return not s.startswith('[') or s.endswith(']')
if all(balanced_section(l) for l in text.splitlines()):
list(split_sections(text)) Type guard
def is_valid_section_line(line: str) -> bool:
s = line.strip()
return not s.startswith('[') or (s.startswith('[') and s.endswith(']')) Try / catch
try:
sections = list(split_sections(text))
except ValueError as e:
if 'Invalid section heading' in str(e):
# fix the unmatched bracket, then retry
...
raise Prevention
- Validate entry_points/required files as INI before parsing.
- Generate section files with configparser.write().
When it happens
Trigger: Calling split_sections (directly or via parse_map) on text containing a line like '[console_scripts' (missing closing bracket), or a line beginning with '[' that is actually data with an embedded bracket.
Common situations: Hand-edited entry_points.txt or requires.txt with a typo in a section header, or data that legitimately starts with '[' but was not meant as a section (and is not bracket-balanced).
Related errors
- Invalid group name
- Duplicate entry point
- Entry points must be listed in groups
- Duplicate group name
- Missing 'Version:' header and/or {} file at path: {}
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/81ef9d79f6b8b66a.json.
Report an issue: GitHub.