pytest-dev/pytest · error · BaseExceptionGroup
errors while tearing down fixture
Error message
errors while tearing down fixture "{self.argname}" of {node} What it means
At fixtures.py:1230 pytest raises BaseExceptionGroup('errors while tearing down fixture ...') when TWO OR MORE exceptions occur while running a fixture's registered finalizers. Single exceptions are re-raised as-is; multiple are grouped (reversed to reflect execution order) so teardown failures are not hidden. The fixture's cached_result and finalizers are cleared before raising.
Solutions
- Inspect the BaseExceptionGroup.subgroups/exceptions to find each root cause; fix the most fundamental one first.
- Make each teardown step defensive (try/except inside the finalizer) so one failure does not cascade.
- Use context managers / addfinalizer per-resource to isolate teardown scope.
- Reproduce with -p no:randomly and a single test to reduce concurrency-induced multi-failures.
Example fix
// before
@pytest.fixture
def svc():
yield start()
stop_db() # may raise
stop_cache()# also raises -> group
// after
@pytest.fixture
def svc():
yield start()
for closer in (stop_db, stop_cache):
try:
closer()
except Exception as e:
logging.warning('teardown failed: %s', e) Defensive patterns
Strategy: try-catch
Try / catch
# In conftest.py, make teardown resilient
import pytest, logging
@pytest.fixture(autouse=True)
def _safe_teardown():
yield
# user teardown handled per-fixture below Prevention
- Wrap each teardown step in try/except and log instead of raising.
- Isolate resource teardown with context managers.
- Run flaky teardowns with -p no:randomly to reduce ordering-induced multi-failures.
When it happens
Trigger: A yield-fixture whose post-yield teardown and one or more addfinalizer callbacks all raise; multiple dependencies of a fixture fail teardown simultaneously; teardown code calling external resources (DB close, file unlock) that error.
Common situations: Cleanup code hitting already-closed resources; finalizers that depend on side effects from other failing finalizers; test environments where multiple external services are torn down and several are unreachable.
Related errors
- errors during test teardown
- class fixtures not supported (maybe in the future)
- Error evaluating while defining fixture ' '. Expected a…
- import error in
- parsefactories() requires holder or node_or_obj
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/5bd26589b2af6b77.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/fixtures.py:1230
exceptions: list[BaseException] = []
while self._finalizers:
fin = self._finalizers.pop()
try:
fin()
except BaseException as e:
exceptions.append(e)
node = request.node
# Even if finalization fails, we invalidate the cached fixture
# value and remove all finalizers because they may be bound methods
# which will keep instances alive.
self.cached_result = None
self._finalizers.clear()
if len(exceptions) == 1:
raise exceptions[0]
elif len(exceptions) > 1:
msg = f'errors while tearing down fixture "{self.argname}" of {node}'
raise BaseExceptionGroup(msg, exceptions[::-1])
def execute(self, request: SubRequest) -> FixtureValue:
"""Return the value of this fixture, executing it if not cached."""
# Ensure that the dependent fixtures requested by this fixture are loaded.
# This needs to be done before checking if we have a cached value, since
# if a dependent fixture has their cache invalidated, e.g. due to
# parametrization, they finalize themselves and fixtures depending on it
# (which will likely include this fixture) setting `self.cached_result = None`.
# See #4871
requested_fixtures_that_should_finalize_us = []
for argname in self.argnames:
fixturedef = request._get_active_fixturedef(argname)
# Saves requested fixtures in a list so we later can add our finalizer
# to them, ensuring that if a requested fixture gets torn down we get torn
# down first. This is generally handled by SetupState, but still currently
# needed when this fixture is not parametrized but depends on a parametrized
# fixture.
requested_fixtures_that_should_finalize_us.append(fixturedef)View on GitHub (pinned to 0d6fbdeffa)