python/cpython · critical · RuntimeError
{name!r} was slated for removal after Python {remove_formatt
Error message
{name!r} was slated for removal after Python {remove_formatted} alpha What it means
Internal CPython helper _deprecated(name, remove=...) (used to retire stdlib APIs) raises RuntimeError when the specified removal version has been reached or passed: either the running version is newer than remove, or it equals remove and the release is past alpha. It exists to make forgotten removals fail loudly in CI rather than silently shipping dead API.
Source
Thrown at Lib/_py_warnings.py:889
_DEPRECATED_MSG = "{name!r} is deprecated and slated for removal in Python {remove}"
def _deprecated(name, message=_DEPRECATED_MSG, *, remove, _version=sys.version_info):
"""Warn that *name* is deprecated or should be removed.
RuntimeError is raised if *remove* specifies a major/minor tuple older than
the current Python version or the same version but past the alpha.
The *message* argument is formatted with *name* and *remove* as a Python
version tuple (e.g. (3, 11)).
"""
remove_formatted = f"{remove[0]}.{remove[1]}"
if (_version[:2] > remove) or (_version[:2] == remove and _version[3] != "alpha"):
msg = f"{name!r} was slated for removal after Python {remove_formatted} alpha"
raise RuntimeError(msg)
else:
msg = message.format(name=name, remove=remove_formatted)
_wm.warn(msg, DeprecationWarning, stacklevel=3)
# Private utility function called by _PyErr_WarnUnawaitedCoroutine
def _warn_unawaited_coroutine(coro):
msg_lines = [
f"coroutine '{coro.__qualname__}' was never awaited\n"
]
if coro.cr_origin is not None:
import linecache, traceback
def extract():
for filename, lineno, funcname in reversed(coro.cr_origin):
line = linecache.getline(filename, lineno)
yield (filename, lineno, funcname, line)
msg_lines.append("Coroutine created at (most recent call last)\n")
msg_lines += traceback.format_list(list(extract()))View on GitHub (pinned to bc6749cc3b)
Solutions
- If you maintain a fork/vendor copy of CPython Lib, update the remove= tuple of the offending _deprecated call to a future version or delete the dead API entirely
- Never call the private _py_warnings._deprecated from application code; use warnings.warn or warnings.deprecated instead
- Re-sync your checkout so Lib/ matches the running interpreter version
Example fix
// before
_deprecated('ssl.wrap_socket', remove=(3, 12)) # RuntimeError on 3.13
# after
_deprecated('ssl.wrap_socket', remove=(3, 14)) # or remove the API outright Defensive patterns
Strategy: validation
Validate before calling
# CPython maintainers only
import sys
assert sys.version_info[:2] < remove or sys.version_info[3] == 'alpha', \
f'removal version {remove} already reached' Prevention
- Never call private _py_warnings._deprecated from applications
- Keep remove= tuples in lockstep with the milestone branch when backporting
- CI should run against the target release so stale removals raise immediately
When it happens
Trigger: Only triggerable inside CPython's own Lib/ code or by importing and calling _py_warnings._deprecated directly with a stale remove tuple; e.g. _deprecated('old_api', remove=(3, 12)) on Python 3.13+. Also fires for stdlib modules whose removal bump was merged but the version check still points at an older release.
Common situations: Vendoring or forking CPython Lib code and carrying old _deprecated calls forward; checking out mismatched Lib/ and interpreter versions in a build; patching _version to a tuple that trips the comparison in tests.
Related errors
- Cannot exit %r without entering first
- Expected an object of type str for 'message', not {type(mess
- {cls.__name__}() takes no arguments
- @deprecated decorator with non-None category must be applied
- 'import warnings' failed; traceback:\n
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/1fc44025ea0b589d.
Report an issue: GitHub.