pytest-dev/pytest · error · ValueError
tmp_path_retention_count must be >= 0. Current input
Error message
tmp_path_retention_count must be >= 0. Current input: {count}. What it means
TempPathFactory.from_config() reads the ini option tmp_path_retention_count, coerces it to int, and rejects negatives. The count governs how many past basetemp directories pytest keeps around between runs; zero is valid (keep none) but a negative value is meaningless, so it fails fast during session configuration rather than later producing an empty cleanup loop.
Solutions
- Set tmp_path_retention_count to 0 or a positive integer (0 = purge all old basetemps, default is 3).
- If you want minimal disk use, set tmp_path_retention_policy = 'none' or 'all' alongside a non-negative count.
- Search all config files pytest loads (pyproject.toml, pytest.ini, tox.ini, setup.cfg) plus -o overrides for the offending value.
Example fix
# before — pyproject.toml [tool.pytest.ini_options] tmp_path_retention_count = -1 # after [tool.pytest.ini_options] tmp_path_retention_count = 0
Defensive patterns
Strategy: validation
Validate before calling
# In conftest.py — validate at session start before TempPathFactory reads it.
import pytest
def pytest_configure(config):
count = int(config.getini("tmp_path_retention_count"))
if count < 0:
raise pytest.UsageError(
f"tmp_path_retention_count must be >= 0, got {count}"
) Type guard
def is_valid_retention_count(value) -> bool:
try:
return int(value) >= 0
except (TypeError, ValueError):
return False Try / catch
# Config is read before tests run; catching at runtime is too late. # Validate in CI with a grep instead: # rg "tmp_path_retention_count\\s*=\\s*-[0-9]" pyproject.toml pytest.ini tox.ini
Prevention
- Keep tmp_path_retention_count at 0 or above (default is 3).
- Add a pre-commit grep for `tmp_path_retention_count = -` to catch typos.
- Remember 0 is valid (purge all); you never need a negative value.
When it happens
Trigger: Setting `tmp_path_retention_count = -1` (or any negative) in pyproject.toml [tool.pytest.ini_options], pytest.ini, tox.ini, or setup.cfg [pytest]. The error fires at session start, before any test runs.
Common situations: Typo (e.g. `-1` instead of `1`); copy-paste from a docs example that used 0; misunderstanding the option as 'keep last N including future' and using a sentinel; migrating from keep_env or older tmpdir options.
Related errors
- ' ' is not recognized as a logging level name for ' '…
- : config option ' ' expects a string, got
- : config option ' ' expects one of , got
- : config option ' ' expects one of , got
- is not a normalized and relative path
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/98f4c88266d36623.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/tmpdir.py:97
# Register cleanups for session finish. Also called atexit as a last
# resort if sessionfinish for some reason doesn't happen.
self._exit_stack = ExitStack()
@classmethod
def from_config(
cls,
config: Config,
*,
_ispytest: bool = False,
) -> TempPathFactory:
"""Create a factory according to pytest configuration.
:meta private:
"""
check_ispytest(_ispytest)
count = int(config.getini("tmp_path_retention_count"))
if count < 0:
raise ValueError(
f"tmp_path_retention_count must be >= 0. Current input: {count}."
)
policy: RetentionType = config.getini("tmp_path_retention_policy")
return cls(
given_basetemp=config.option.basetemp,
trace=config.trace.get("tmpdir"),
retention_count=count,
retention_policy=policy,
_ispytest=True,
)
def _ensure_relative_to_basetemp(self, basename: str) -> str:
basename = os.path.normpath(basename)
if (self.getbasetemp() / basename).resolve().parent != self.getbasetemp():
raise ValueError(f"{basename} is not a normalized and relative path")
return basenameView on GitHub (pinned to 0d6fbdeffa)