Skip to content
Latchkey

tox Uses a Stale Environment - Recreate After Dependency Changes in CI

tox caches each environment under .tox and only reinstalls when it detects a change. When deps change in a way tox does not notice (or a cached .tox is restored), tests run against stale packages and fail confusingly.

What this error means

A tox run fails with a missing or wrong-version package even though requirements/deps were updated. Deleting .tox (or passing --recreate) fixes it - proving the environment was stale, not the code.

tox output
py312 run-test: ModuleNotFoundError: No module named 'httpx'
# httpx was added to deps, but .tox/py312 was restored from cache and not updated

Common causes

Cached .tox env not refreshed

tox reuses .tox/<env> and reinstalls only on detected changes. A restored cache or an indirect dependency change can leave the env stale.

Dependencies declared outside tox’s change detection

Deps pulled from a constraints file or a dynamically generated requirement may change without tox re-provisioning the env.

How to fix it

Recreate the environment

Force tox to rebuild the env so it installs current dependencies.

Terminal
tox --recreate          # or -r
# target one env
tox -r -e py312

Key the .tox cache on the dependency files

When caching .tox in CI, include the dependency inputs in the cache key so a change busts it.

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: .tox
    key: tox-${{ hashFiles('tox.ini','pyproject.toml','requirements*.txt') }}

How to prevent it

  • Recreate tox envs when dependencies change, or key the cache on dep files.
  • Avoid restoring a .tox cache across unrelated dependency states.
  • Declare all deps where tox can see them for change detection.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →