{"record":{"id":"81ef9d79f6b8b66a","repo":"pypa/pip","slug":"invalid-section-heading","errorCode":null,"errorMessage":"Invalid section heading","messagePattern":"Invalid section heading","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/pkg_resources/__init__.py","lineNumber":3538,"sourceCode":"def split_sections(s: _NestedStr) -> Iterator[tuple[str | None, list[str]]]:\n    \"\"\"Split a string or iterable thereof into (section, content) pairs\n\n    Each ``section`` is a stripped version of the section header (\"[section]\")\n    and each ``content`` is a list of stripped lines excluding blank lines and\n    comment-only lines.  If there are any such lines before the first section\n    header, they're returned in a first ``section`` of ``None``.\n    \"\"\"\n    section = None\n    content = []\n    for line in yield_lines(s):\n        if line.startswith(\"[\"):\n            if line.endswith(\"]\"):\n                if section or content:\n                    yield section, content\n                section = line[1:-1].strip()\n                content = []\n            else:\n                raise ValueError(\"Invalid section heading\", line)\n        else:\n            content.append(line)\n\n    # wrap up last segment\n    yield section, content\n\n\ndef _mkstemp(*args, **kw):\n    old_open = os.open\n    try:\n        # temporarily bypass sandboxing\n        os.open = os_open\n        return tempfile.mkstemp(*args, **kw)\n    finally:\n        # and then put it back\n        os.open = old_open\n\n","sourceCodeStart":3520,"sourceCodeEnd":3556,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_vendor/pkg_resources/__init__.py#L3520-L3556","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: entry_points.txt\n// [console_scripts\n// mycli = pkg:main\n\n// after\n// [console_scripts]\n// mycli = pkg:main","handlingStrategy":"validation","validationCode":"import re\ndef has_valid_section_headers(text: str) -> bool:\n    for line in text.strip().splitlines():\n        s = line.strip()\n        if s.startswith('['):\n            if not s.endswith(']'):\n                return False\n    return True","typeGuard":"def is_valid_section_line(line: str) -> bool:\n    s = line.strip()\n    if s.startswith('['):\n        return s.endswith(']')\n    return True\n","tryCatchPattern":"from pkg_resources import split_sections\ntry:\n    sections = list(split_sections(text))\nexcept ValueError:\n    # fix malformed headers and retry, or log the error\n    text = fix_section_headers(text)\n    sections = list(split_sections(text))\n","preventionTips":["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."],"tags":["metadata","pkg-resources","parsing","section-header","configparser"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}