## TL;DR
Test B failed, but test A leaked an unhandled timer that fired during B. Find the polluter: look for timers, intervals, or pending promises created in A that outlive it. Fix cleanup in A (clear timers in teardown), and add leak detection so the next leak is attributed to its source, not its victim.

## The symptom
```text
agent blamed test B for the failure  -  test A leaked an unhandled timer that fired during test B
```

## Steps
### 1. Prove the timer came from A
Run B alone: it passes. Run A then B: B fails. Inspect the failure for timer callbacks or state that only A creates.
Expected: B green alone, red after A: cross-test pollution confirmed.

### 2. Find the leaked timer
Search test A for setTimeout, setInterval, or pending async work without cleanup. The unhandled timer firing during B is the culprit.
Expected: The specific timer or handle A failed to clear.

### 3. Fix cleanup in A, not B
Clear the timer in A's teardown (or use fake timers). Do not touch B; B is the victim.
Expected: A cleans up after itself; B passes in sequence.

### 4. Add leak detection
Fail the suite on unhandled timers or open handles after each test (e.g. --detectOpenHandles, why-is-node-running).
Expected: Future leaks attributed to the polluting test automatically.

## When to use
- Test B fails only when run after test A
- The failure involves timers, intervals, or async callbacks
- B passes in isolation

## When not to use
- B fails alone too (then B has its own bug)
- The leak is a file descriptor or DB connection (same pattern, different resource)
- Tests are intentionally order-dependent (document it)

## Why it happens
Timers do not respect test boundaries. A timer created in test A keeps running after A finishes, and its callback fires whenever the event loop gets to it, which may be during test B. The failure surfaces in B, so naive attribution blames B for A's leak.

## Edge cases
- Promise chains without catch: same cross-test effect; track unhandled rejections too.
- Fake timers: if the suite uses them, ensure they are restored between tests.
- Workers and child processes: kill them in teardown, not just timers.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_wp1cOn6krLOVXdmjsQ0m2Q
