{
  "id": 11061226,
  "title": "stripe told me my webhook was broken. i found the email 17 days later.",
  "url": "https://urgent.news/2026/09/30/stripe-told-me-my-webhook-was-broken-i-found-the-email-17-days-later",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-30T23:56:14.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/motzumoto/stripe-told-me-my-webhook-was-broken-i-found-the-email-17-days-later-4kaj"
  },
  "original_language": "en",
  "account": "Akiko's premium tier on Stripe went through a series of webhook failures over ten weeks. She only discovered the issue when a read email from Stripe, buried under 17 days of unread messages, alerted her. The problem stemmed from an outdated Express backend that was moved to Next.js, causing delivery issues when the Stripe keys were absent from the .env file. The catch block in the code transformed any error mentioning Stripe into a 400 response, confusing the distinction between a missing configuration and a bad signature. The dashboard last recorded an event on June 3, with the Express backend being retired on June 11. The first failed delivery occurred on July 22, and Stripe disabled the endpoint on July 31 after 10 attempts over nine days. Following the discovery, Akiko found another bug in the same file, where six variables were formatted as NAME = value with spaces around the equals, leading dotenv to read them as variables called NAME with a trailing space, rendering them undefined. As Akiko delved into how premium subscriptions end, she realized that the code only checked the current_period_end date without considering the expires_at date, causing lapsed subscriptions to run indefinitely. The issue was compounded by multiple date columns that didn't mirror each other properly, resulting in two lapsed subscriptions with a past expires_at date and a NULL current_period_end date. The AI-powered code would mistakenly provide lifetime access to a subscription that had ended in May. To rectify the situation, Akiko implemented changes to deny access if either date was in the past, leaving NULL in both to signify a lifetime grant. She also added a daily sweep to clear active subscriptions whose dates had passed. The fix was tested against a clone of the real table, successfully revoking the two lapsed rows without affecting lifetime grants. Akiko recommends readers to review their Stripe emails to avoid similar issues.",
  "summary": "this one's a bit embarrassing. Akiko has a premium tier that runs through Stripe, and for about ten weeks every webhook Stripe sent her dashboard failed. i had no idea. i only found out because of an email from Stripe that had been sitting unread for seventeen days. what happened i retired the old Express backend on the dashboard and moved everything into Next.js. the Stripe keys lived in the…",
  "key_points": [
    "Akiko experienced 10-week series of webhook failures on Stripe premium tier",
    "Outdated Express backend moved to Next.js caused delivery issues",
    "Akiko discovered email from Stripe buried under 17 days of unread messages"
  ],
  "editors_take": "Akiko's experience highlights the importance of monitoring Stripe emails and having robust error handling in place to avoid prolonged webhook failures and unintended subscription behavior.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}