From 6b1adb394b1d660dcfd2d00bc70e93fb5e623a37 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Thu, 25 Jun 2026 17:35:17 +0200 Subject: [PATCH] fix(products): hard-block dead composite slugs so /products/ 404s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zombie slugs (codex-polymarket, codex-kalshi, predexon-kalshi, predexon-limitless, predexon-polymarket) survived past the pre-collapse pm-api-latency split via stale materialize-worker snapshots. The pm-api-latency cohort fix in #725 stops the bench from feeding them, but Upstash keeps the per-slug blobs around for TTL. Filter them out in buildProviders() so getProvider() returns undefined, the /products/ route falls through to notFound(), the sitemap stops listing them, and related/compare candidates already filter them via the same set in related-providers.ts. Bumped buildProviders cache key v2→v3 to invalidate the ISR profile list immediately on deploy instead of waiting for the next benchmarks-tag revalidation. --- src/lib/providers.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/lib/providers.ts b/src/lib/providers.ts index 2c049a6b..202879eb 100644 --- a/src/lib/providers.ts +++ b/src/lib/providers.ts @@ -378,7 +378,9 @@ async function buildProviders(): Promise { }); } - const profiles = Array.from(byKey.values()); + const profiles = Array.from(byKey.values()).filter( + (p) => !DEAD_COMPOSITE_SLUGS.has(p.slug), + ); profiles.sort((a, b) => { if (a.wins !== b.wins) return b.wins - a.wins; if (a.appearances.length !== b.appearances.length) { @@ -389,6 +391,20 @@ async function buildProviders(): Promise { return profiles; } +// Zombie slugs from the pre-collapse pm-api-latency split. The bench +// now ranks the parent provider only (codex, predexon), but stale +// materialize-worker snapshots can recreate ghost /products/ +// pages with no data. Hard-block so getProvider() returns undefined and +// the route 404s cleanly. Keep in sync with the same set in +// related-providers.ts. +const DEAD_COMPOSITE_SLUGS = new Set([ + "codex-kalshi", + "codex-polymarket", + "predexon-kalshi", + "predexon-limitless", + "predexon-polymarket", +]); + // Cohort venues that should have a /products/ page even when no // bench in benchmarks/ ranks them. Imported as a flat list here to // avoid a build-time cycle with the perp-stats module. @@ -420,7 +436,7 @@ const PERP_VENUE_SEED = [ * bump this key when the buildProviders() output shape changes. */ const buildProvidersCached = unstable_cache( buildProviders, - ["providers-v2"], + ["providers-v3"], { revalidate: 60, tags: ["benchmarks"] }, );