pytest-dev/pytest · error · RuntimeError
Cannot exit {self!r} without entering first
Error message
Cannot exit {self!r} without entering first What it means
WarningsRecorder.__exit__ raises RuntimeError if called on an instance that was not entered first. The recorder tracks entered state and rejects unbalanced exit.
Source
Thrown at src/_pytest/recwarn.py:255
if self._entered:
__tracebackhide__ = True
raise RuntimeError(f"Cannot enter {self!r} twice")
_list = super().__enter__()
# record=True means it's None.
assert _list is not None
self._list = _list
warnings.simplefilter("always")
return self
def __exit__(
self,
exc_type: type[BaseException] | None,
exc_val: BaseException | None,
exc_tb: TracebackType | None,
) -> None:
if not self._entered:
__tracebackhide__ = True
raise RuntimeError(f"Cannot exit {self!r} without entering first")
super().__exit__(exc_type, exc_val, exc_tb)
# Built-in catch_warnings does not reset entered state so we do it
# manually here for this context manager to become reusable.
self._entered = False
@final
class WarningsChecker(WarningsRecorder):
def __init__(
self,
expected_warning: type[Warning] | tuple[type[Warning], ...] = Warning,
match_expr: str | re.Pattern[str] | None = None,
*,
_ispytest: bool = False,
) -> None:
check_ispytest(_ispytest)View on GitHub (pinned to 98b357f69e)
Solutions
- Always use the `with` statement so enter/exit are balanced automatically.
- If managing enter/exit manually, guard exit with a check of the entered state.
- Ensure __enter__ succeeds before any code path can reach __exit__.
Example fix
// before
recorder.__exit__(None, None, None) # never entered
// after
with recorder:
... Defensive patterns
Strategy: validation
Validate before calling
if not getattr(recorder, '_entered', False):
raise RuntimeError('recorder not entered; cannot exit')
recorder.__exit__(None, None, None) Prevention
- Always use the `with` statement for balanced enter/exit.
- Never call __exit__ manually without a successful __enter__.
- Guard manual cleanup with an entered-state check.
When it happens
Trigger: Manually calling recorder.__exit__(...) without a prior __enter__, or a code path that exits twice (the second after state was reset). Hits recwarn.py:255.
Common situations: Direct manipulation of the context-manager protocol; a cleanup/finally block that exits a recorder that was never entered due to an earlier error.
Related errors
- Cannot enter {self!r} twice
- Unexpected keyword arguments passed to pytest.warns: {argnam
- {func!r} object (type: {type(func)}) must be callable
- {cls!r} not found in warning list
- exceptions must be derived from Warning, not %s
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/6ca40e4edafdd9a4.json.
Report an issue: GitHub.