tiangolo/fastapi · error · RuntimeError

Release notes section for

Error message

Release notes section for {version} in {release_notes_file} is empty

What it means

Raised by get_release_notes_body() in scripts/prepare_release.py:96 when the version section heading exists but its body (text up to the next '## ' heading, stripped) is empty (scripts/prepare_release.py:94-95). The release-notes command is meant to output the changelog body for tooling, so an empty body is treated as an error rather than emitting nothing.

Solutions

  1. Populate the section with at least one changelog entry under the '## <version>' heading.
  2. Remove the empty heading if the version is not being released.
  3. Re-run release-notes once the section has content.

Example fix

<!-- before -->
## 1.2.3 (2026-01-01)

## 1.2.2 (2025-12-01)
<!-- after -->
## 1.2.3 (2026-01-01)
- Fixed login redirect

## 1.2.2 (2025-12-01)
Defensive patterns

Strategy: validation

Validate before calling

import re
from pathlib import Path

def section_has_body(path: Path, version: str) -> bool:
    text = path.read_text(encoding="utf-8")
    m = re.search(rf"(?m)^## {re.escape(version)}(?: \([^)]+\))?$", text)
    if not m:
        return False
    nxt = re.search(r"(?m)^## ", text[m.end():])
    body = text[m.end(): m.end() + (nxt.start() if nxt else len(text) - m.end())].strip()
    return bool(body)

Try / catch

try:
    body = get_release_notes_body(content, version, release_notes_file)
except RuntimeError as e:
    if "is empty" in str(e):
        raise SystemExit(f"Add changelog entries under ## {version}") from e
    raise

Prevention

When it happens

Trigger: Running `release-notes` for a version whose '## X.Y.Z' heading was added but contains no bullet points (e.g. a placeholder section), or where all content between headings is whitespace.

Common situations: prepare created the heading but no PR descriptions were added under it. A maintainer added the heading as a stub. Content was accidentally deleted leaving the heading orphaned.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/501988be351de24f. Report an issue: GitHub.

Appendix: source

Thrown at scripts/prepare_release.py:96

        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(
            envvar="PREPARE_RELEASE_BUMP",
            help="The release bump to make: major, minor, or patch.",
        ),
    ],
    version_file: Annotated[
        Path,
        typer.Option(
            envvar="PREPARE_RELEASE_VERSION_FILE",

View on GitHub (pinned to 3e8d1526d8)