Case File · INV-0051
Pricing page froze 25 minutes after a CMS update
A missing tag mapping and a silent TypeError combined to block every revalidation job — leaving SimUser AI's pricing page stuck on old data right before a 15% price repositioning went live.
The Symptom
On April 16, 2026, Felipe Aguiar (Head of Marketing, SimUser AI) pushed a 15% price update across all plans via Contentful at 11:20 UTC. At 11:45 UTC a lead confirmed the /pricing page still showed the old numbers. The marketing team had already shared the updated pricing in an email blast — visitors clicking through saw stale data.
Evidence Board
tag: "revalidate"path: "/pricing"status: "pending"retries: 3error: "TypeError: Cannot read propertiesof undefined (reading NewImage)at handler (/var/task/index.js:23:45)"deployId: "deploy-20260416-030158"deployVersion:"v2.4.0"timestamp: "2026-04-16T03:02:14Z"
71 rows returned — all paths containing "/pricing"tag: "{deployId}/_N_T_/[locale]/pricing/page"path: "{deployId}/en/pricing"revalidatedAt:"1" ← never revalidated since deploy→ No cache invalidation reached any /pricing variant.
Log group: /aws/lambda/simuser-ai-production-WebsiteRevalidationSeederFunction{"level":"warn","msg":"Tag not found in revalidation table","tag":"pricing-page","pathCount":0,"note":"No paths registered for this tag — skipping"}
- /
- /pricing
- /features
- /blog/simuser-ai-v2-launch
- /blog/…
Where the Pipeline Broke
Two overlapping bugs blocked every revalidation attempt. Hover each X to see the failing code.
Systemic Blast Radius
The TypeError in the Subscriber handler affected every route that had a queued revalidation job — not just /pricing. Any page touched by a DynamoDB Streams event during this window was silently stuck.
- /
- /pricing
- /features
- /blog/simuser-ai-v2-launch
- /blog/…
Symptom → Root Cause
- 1
Symptom: /pricing shows stale prices
↳ Lead reports old plan prices; CMS publish was 25 min ago.
- 2
DynamoDB job stuck at retries: 3
↳ TypeError on NewImage blocks all revalidation jobs — any DELETE event crashes the handler.
- 3
Seeder skips /pricing entirely
↳ Tag 'pricing-page' has no paths registered in the revalidation table; pathCount: 0.
- 4
Root cause: two overlapping bugs
↳ Missing tag map + unguarded NewImage access = no revalidation ever reaches Next.js.
Root Cause & Fix
Bug 1 — Missing tag mapping
The CMS webhook sends the tag pricing-page, but no entry in the DynamoDB table maps that tag to the /pricing path. The Seeder logs a warn and exits without queuing any invalidation.
Bug 2 — Unguarded NewImage access
The RevalidationEventsSubscriber reads event.Records[i].dynamodb.NewImage unconditionally. DynamoDB Streams DELETE events omit NewImage, causing a TypeError that puts every affected job into an unrecoverable retries: 3 / status: pending state.
// handler (/var/task/index.js:23)
const newImage = record.dynamodb.NewImage; // crashes on DELETE events
await revalidatePath(newImage.path.S);// handler (/var/task/index.js:23)
const newImage = record.dynamodb?.NewImage;
if (!newImage) return; // guard: DELETE
await revalidatePath(newImage.path.S);Additionally: register the tag pricing-page → /pricing in the revalidation table and audit all other CMS tags to ensure they map to the correct Next.js paths.
Outcome
Without CauseFlow: ~3 hrs of cross-team debugging across CloudWatch, DynamoDB console, and Lambda logs — with the reputational cost of stale pricing visible to inbound leads during a live price repositioning.
With CauseFlow: root cause surfaced in 25 minutes, fix committed before any further leads landed on the page.
Stop chasing logs.
Start building product.
Connect your stack in minutes and investigate real incidents on your infra. No contract, no card.