tiangolo/fastapi · error · RuntimeError
Could not find release notes section for {version} in {relea
Error message
Could not find release notes section for {version} in {release_notes_file} What it means
Raised by get_release_notes_body() in scripts/prepare_release.py:88 when searching for the '## X.Y.Z' heading for the requested version yields no match (version_heading.search returns None at scripts/prepare_release.py:86). This command is meant to print the body of an existing release section; if the section was never created it cannot proceed.
Source
Thrown at scripts/prepare_release.py:88
raise RuntimeError(f"Release notes already contain a section for {version}")
latest_header = f"{RELEASE_NOTES_HEADER}{LATEST_CHANGES_HEADER}\n"
if not content.startswith(latest_header):
raise RuntimeError(f"{release_notes_file} must start with {latest_header!r}")
release_header = f"## {version} ({release_date.isoformat()})"
return content.replace(
latest_header,
f"{RELEASE_NOTES_HEADER}{LATEST_CHANGES_HEADER}\n\n{release_header}\n",
1,
)
def get_release_notes_body(content: str, version: str, release_notes_file: Path) -> str:
version_heading = re.compile(rf"(?m)^## {re.escape(version)}(?: \([^)]+\))?$")
match = version_heading.search(content)
if not match:
raise RuntimeError(
f"Could not find release notes section for {version} in {release_notes_file}"
)
next_match = VERSION_HEADING_PATTERN.search(content, match.end())
end = next_match.start() if next_match else len(content)
body = content[match.end() : end].strip()
if not body:
raise RuntimeError(
f"Release notes section for {version} in {release_notes_file} is empty"
)
return f"{body}\n"
@app.command()
def prepare(
bump: Annotated[
BumpType,
typer.Argument(View on GitHub (pinned to 3e8d1526d8)
Solutions
- Run `prepare <bump>` first so the section for the new version is created.
- Manually add a '## <version> (YYYY-MM-DD)' heading to the release notes file if you bumped the version another way.
- Confirm the heading matches the pattern '## X.Y.Z' or '## X.Y.Z (date)'.
Example fix
<!-- before: version 1.2.3 in file but no section --> ## Latest Changes <!-- after --> ## Latest Changes ## 1.2.3 (2026-01-01) - Initial release
Defensive patterns
Strategy: validation
Validate before calling
import re
from pathlib import Path
def section_present(path: Path, version: str) -> bool:
pat = re.compile(rf"(?m)^## {re.escape(version)}(?: \([^)]+\))?$")
return pat.search(path.read_text(encoding="utf-8")) is not None Try / catch
try:
body = get_release_notes_body(content, version, release_notes_file)
except RuntimeError as e:
if "Could not find release notes section" in str(e):
raise SystemExit(f"Run prepare first to create the {version} section") from e
raise Prevention
- Run prepare before release-notes so the section exists.
- Keep version headings in the '## X.Y.Z (date)' format.
- Validate the release-notes file path is correct.
When it happens
Trigger: Running `python scripts/prepare_release.py release-notes` (which calls get_release_notes_body with the current __version__) when no matching '## <current_version>' heading exists in the release notes file. Happens right after bumping __version__ but before adding the section via prepare.
Common situations: The version file was bumped manually without running prepare, then release-notes is called. The heading uses a different format than VERSION_HEADING_PATTERN expects. The release notes file points at the wrong path.
Related errors
- {release_notes_file} must start with {RELEASE_NOTES_HEADER!r
- {release_notes_file} must start with {latest_header!r}
- Release notes section for {version} in {release_notes_file}
- Number of code include placeholders does not match the numbe
- Number of headers with permalinks does not match the number
AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11).
Data as JSON: /api/errors/259e31a4e35129c3.
Report an issue: GitHub.