tiangolo/fastapi · error · RuntimeError

New version {version} must be greater than current version {

Error message

New version {version} must be greater than current version {current_version}

What it means

Raised by update_version_file() in scripts/prepare_release.py:56 when the requested new version is not strictly greater than the current version (parse_version(version) <= parse_version(current_version) at scripts/prepare_release.py:55). Releases must move forward; equal or lower versions are rejected to prevent regressions in published artifacts and PyPI.

Source

Thrown at scripts/prepare_release.py:56

            f"Expected exactly one __version__ assignment in {version_file}, "
            f"found {len(matches)}"
        )
    return matches[0].group(1)


def bump_version(version: str, bump: BumpType) -> str:
    major, minor, patch = parse_version(version)
    if bump == "major":
        return f"{major + 1}.0.0"
    if bump == "minor":
        return f"{major}.{minor + 1}.0"
    return f"{major}.{minor}.{patch + 1}"


def update_version_file(content: str, version: str, version_file: Path) -> str:
    current_version = get_current_version(content, version_file)
    if parse_version(version) <= parse_version(current_version):
        raise RuntimeError(
            f"New version {version} must be greater than current version {current_version}"
        )
    return VERSION_PATTERN.sub(f'__version__ = "{version}"', content, count=1)


def update_release_notes(
    content: str, version: str, release_date: date, release_notes_file: Path
) -> str:
    if not content.startswith(RELEASE_NOTES_HEADER):
        raise RuntimeError(
            f"{release_notes_file} must start with {RELEASE_NOTES_HEADER!r}"
        )
    if re.search(rf"^## {re.escape(version)}(?: \([^)]+\))?$", content, re.M):
        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}")

View on GitHub (pinned to 3e8d1526d8)

Solutions

  1. Check the current version: python scripts/prepare_release.py current-version --version-file <path>.
  2. Use a larger bump type (minor instead of patch) if the file is already ahead.
  3. Reset the version file to the last released version if it was bumped prematurely.

Example fix

# before — version file already at 1.2.3, asking for patch bump -> 1.2.3 (not greater)
__version__ = "1.2.3"
# after — bump minor or reset first
__version__ = "1.2.2"  # then run: prepare minor
Defensive patterns

Strategy: validation

Validate before calling

def new_gt_current(new: str, current: str) -> bool:
    def t(v):
        a, b, c = v.split(".")
        return (int(a), int(b), int(c))
    return t(new) > t(current)

Try / catch

try:
    new_content = update_version_file(content, version, version_file)
except RuntimeError as e:
    raise SystemExit(f"Refusing to downgrade: {e}") from e

Prevention

When it happens

Trigger: Calling prepare with a version bump that resolves to <= current, or directly calling update_version_file with a lower/equal version. Can happen if the version file was already bumped ahead of the requested bump.

Common situations: Someone manually bumped __version__ before running prepare, so the computed bump (e.g. patch) is not greater than the new current. Two concurrent release attempts race. A hotfix version was passed manually below the released version.

Related errors


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