pestphp/pest · error · AssertionFailedError

Cached failure

Error message

Cached failure

What it means

With test-influence analysis (--tia), Pest caches per-test results and, on later runs, replays the cached verdict for tests unaffected by your changes instead of re-executing them. When the cached status resolves to ReplayType::Failure, Pest rethrows an AssertionFailedError carrying the stored failure message; if that stored message is empty it falls back to the literal text 'Cached failure'. Hitting it means a previously failing test was replayed from the TIA graph, so the test did not actually run this time.

Source

Thrown at src/Concerns/Testable.php:219

        self::$__latestNotes = $method->notes;
        self::$__latestIssues = $method->issues;
        self::$__latestPrs = $method->prs;

        /** @var Tia $tia */
        $tia = Container::getInstance()->get(Tia::class);
        $status = $tia->getStatus(self::$__filename, $this->valueObjectForEvents()->id());
        $replay = ReplayType::fromStatus($status);

        if ($replay !== ReplayType::None) {
            assert($status !== null);

            $this->__replay = $replay;

            match ($replay) {
                ReplayType::Pass, ReplayType::Risky => $this->__beginReplay($replay, $tia),
                ReplayType::Skipped => $this->markTestSkipped($status->message()),
                ReplayType::Incomplete => $this->markTestIncomplete($status->message()),
                ReplayType::Failure => throw new AssertionFailedError($status->message() ?: 'Cached failure'),
            };

            return;
        }

        $recorder = Container::getInstance()->get(Recorder::class);
        assert($recorder instanceof Recorder);

        if ($recorder->isActive()) {
            $recorder->beginTest($this::class, $this->name(), self::$__filename);
        }

        parent::setUp();

        Collectors::armAll($recorder);

        $beforeEach = TestSuite::getInstance()->beforeEach->get(self::$__filename)[1];

View on GitHub (pinned to 1af74a215c)

Solutions

  1. Re-run the same test without --tia (or delete the TIA cache) to execute the test for real and get the full failure output.
  2. Treat the cached verdict as genuine: fix the underlying failing test, then let the next --tia run record a passing status.
  3. If the cache is stale or suspicious (e.g., after a big rebase), clear the TIA cache directory so the next run records fresh statuses.

Example fix

# before
vendor/bin/pest --tia          # replays: 'Cached failure' with no diff
# after
vendor/bin/pest tests/Unit/ThatTest.php   # real run, full diff
rm -rf .pest  # or clear the tia cache to force fresh recording
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Running vendor/bin/pest --tia after an earlier failing run, then editing files the TIA graph considers unrelated to that test; a failure status recorded without a message (empty diff/message in the cache), producing the 'Cached failure' default text; a stale TIA cache left over from before a branch switch.

Common situations: Teams enabling TIA to speed up large suites; CI or local caches (.pest tia graph) surviving branch switches or force-pushes; debugging confusion because the failure output shows no diff — only the cached message.

Related errors


AI-assisted analysis of pestphp/pest@1af74a215c (2026-08-21). Data as JSON: /api/errors/5a63fdfa50f2f59c. Report an issue: GitHub.