From 7a3c98d0036e4773657bc8d8b8700c47bb08c0aa Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Sat, 18 Jul 2026 13:16:03 +0200 Subject: [PATCH] spec: unstable_noStore() when returning draft placeholders (kills poisoned aggregate cache without cache-key bumps) --- src/lib/spec.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lib/spec.ts b/src/lib/spec.ts index 1393b62e..231dd22b 100644 --- a/src/lib/spec.ts +++ b/src/lib/spec.ts @@ -10,7 +10,7 @@ */ import { cache } from "react"; -import { unstable_cache } from "next/cache"; +import { unstable_cache, unstable_noStore } from "next/cache"; import type { Benchmark } from "@/types/benchmark"; import type { Spec } from "@/lib/spec-schema"; // Imported from the isolated alias module (NOT @/lib/chains) to avoid @@ -483,6 +483,16 @@ export const loadAllBenchmarksSafe = cache( return await loadAllBenchmarksCached(); } catch (err) { if (err instanceof AllBenchmarksDraftError) { + // Opt this render out of every cache layer (ISR + CDN edge). When + // the aggregate quorum is lost (SRH stuck, Redis blackout, worker + // starved) the placeholder response is a degraded surrogate, NOT + // ground truth. Without noStore the placeholder HTML would sit at + // Vercel Edge for `revalidate` seconds and — under stale-while- + // revalidate — for hours after backend recovery, since SWR only + // refreshes on cache miss. Marking the response no-store forces + // every subsequent hit to re-render, which immediately picks up + // real data as soon as SRH is back — no cache-key bump, no deploy. + unstable_noStore(); const specs = await loadSpecs(); return specs .map((s) => draftPlaceholderForSpec(s))