{"record":{"id":"54d50a271b2ff7f3","repo":"tiangolo/fastapi","slug":"release-notes-already-contain-a-section-for-versi","errorCode":null,"errorMessage":"Release notes already contain a section for {version}","messagePattern":"Release notes already contain a section for (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"scripts/prepare_release.py","lineNumber":70,"sourceCode":"\ndef update_version_file(content: str, version: str, version_file: Path) -> str:\n    current_version = get_current_version(content, version_file)\n    if parse_version(version) <= parse_version(current_version):\n        raise RuntimeError(\n            f\"New version {version} must be greater than current version {current_version}\"\n        )\n    return VERSION_PATTERN.sub(f'__version__ = \"{version}\"', content, count=1)\n\n\ndef update_release_notes(\n    content: str, version: str, release_date: date, release_notes_file: Path\n) -> str:\n    if not content.startswith(RELEASE_NOTES_HEADER):\n        raise RuntimeError(\n            f\"{release_notes_file} must start with {RELEASE_NOTES_HEADER!r}\"\n        )\n    if re.search(rf\"^## {re.escape(version)}(?: \\([^)]+\\))?$\", content, re.M):\n        raise RuntimeError(f\"Release notes already contain a section for {version}\")\n\n    latest_header = f\"{RELEASE_NOTES_HEADER}{LATEST_CHANGES_HEADER}\\n\"\n    if not content.startswith(latest_header):\n        raise RuntimeError(f\"{release_notes_file} must start with {latest_header!r}\")\n\n    release_header = f\"## {version} ({release_date.isoformat()})\"\n    return content.replace(\n        latest_header,\n        f\"{RELEASE_NOTES_HEADER}{LATEST_CHANGES_HEADER}\\n\\n{release_header}\\n\",\n        1,\n    )\n\n\ndef get_release_notes_body(content: str, version: str, release_notes_file: Path) -> str:\n    version_heading = re.compile(rf\"(?m)^## {re.escape(version)}(?: \\([^)]+\\))?$\")\n    match = version_heading.search(content)\n    if not match:\n        raise RuntimeError(","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/scripts/prepare_release.py#L52-L88","documentation":"Raised by update_release_notes() in scripts/prepare_release.py:70 when the release notes already contain a '## X.Y.Z' or '## X.Y.Z (date)' heading for the version being prepared (regex at scripts/prepare_release.py:69). The release process must not create duplicate version sections.","triggerScenarios":"Running prepare twice for the same version, or for a version whose section was already added manually. The VERSION_HEADING_PATTERN detects an existing heading identical to the target version.","commonSituations":"A previous prepare run partially completed (section added, version file not bumped). Re-running a CI job that re-triggers prepare. Manual draft of the section before the tool runs.","solutions":["Check if the version was already released: python scripts/prepare_release.py release-notes --version-file ... --release-notes-file ...","If the section is a stale draft, delete it and re-run prepare.","If the version is genuinely already released, skip prepare for that version."],"exampleFix":"<!-- before: duplicate 1.2.3 section -->\n## 1.2.3 (2026-01-01)\n- first\n\n## 1.2.3 (2026-01-02)\n- second\n<!-- after: keep only one -->\n## 1.2.3 (2026-01-01)\n- first\n- second","handlingStrategy":"validation","validationCode":"import re\nfrom pathlib import Path\n\ndef version_section_exists(path: Path, version: str) -> bool:\n    pat = re.compile(rf\"(?m)^## {re.escape(version)}(?: \\([^)]+\\))?$\")\n    return pat.search(path.read_text(encoding=\"utf-8\")) is not None","typeGuard":null,"tryCatchPattern":"try:\n    updated = update_release_notes(content, version, d, release_notes_file)\nexcept RuntimeError as e:\n    if \"already contain a section\" in str(e):\n        raise SystemExit(f\"Version {version} already released: {e}\") from e\n    raise","preventionTips":["Run prepare once per release; do not re-run after the section is added.","If a previous run half-completed, revert the release notes file before retrying.","Check release-notes for the version before running prepare."],"tags":["release","validation","versioning"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}