[PR #8124] [CLOSED] fix(stripe): handle empty subscription list in onSubscriptionUpdated webhook #16006

Closed
opened 2026-04-13 10:20:51 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/8124
Author: @JoDrm
Created: 2/24/2026
Status: Closed

Base: mainHead: fix/stripe-webhook-empty-subscription-list


📝 Commits (10+)

📊 Changes

1004 files changed (+103697 additions, -31625 deletions)

View changed files

.claude/rules/release.md (+123 -0)
📝 .cspell/alt-languages.txt (+9 -1)
📝 .cspell/company-names.txt (+2 -1)
📝 .cspell/names.txt (+22 -1)
📝 .cspell/tech-terms.txt (+9 -1)
📝 .cspell/third-party.txt (+4 -1)
📝 .github/ISSUE_TEMPLATE/bug_report.yml (+1 -1)
.github/actions/setup-playwright/action.yml (+68 -0)
.github/workflows/adapter-tests.yml (+0 -71)
.github/workflows/auto-cherry-pick-to-main.yml (+0 -337)
.github/workflows/cherry-pick-to-main.yml (+0 -325)
📝 .github/workflows/ci.yml (+26 -33)
.github/workflows/claude.yml (+53 -0)
📝 .github/workflows/e2e.yml (+80 -36)
📝 .github/workflows/preview.yml (+7 -6)
📝 .github/workflows/release.yml (+9 -2)
📝 .gitignore (+2 -0)
.npmrc (+0 -1)
📝 .nvmrc (+1 -1)
.postmortem/client-side-import-server.md (+141 -0)

...and 80 more files

📄 Description

Bug

onSubscriptionUpdated in the Stripe plugin crashes with TypeError: Cannot read properties of undefined (reading 'id') when a customer.subscription.updated webhook event is received for a customer that has no subscription records in the database.

Root Cause

In packages/stripe/src/hooks.ts, when the subscription lookup by stripeSubscriptionId fails, the code falls back to querying by stripeCustomerId. If the result is an empty array (subs.length === 0), the else branch assigns subscription = subs[0]! which is undefined. The subsequent subscription.id access then crashes.

// Before (line ~314)
} else {
    subscription = subs[0]!; // undefined when subs is empty
}

// Later (line ~335)
where: [{ field: "id", value: subscription.id }] // TypeError!

Fix

Add an early return when subs is empty, consistent with the existing guard for subs.length > 1 with no active subscription.

if (subs.length === 0) {
    ctx.context.logger.warn(
        `Stripe webhook warning: No subscription found for customerId: ${customerId}, ignoring event`,
    );
    return;
}

How to reproduce

  1. Have a Stripe customer with no subscription records in the database (e.g. a customer who only made one-time payments)
  2. Trigger a customer.subscription.updated webhook event for that customer
  3. The webhook handler crashes with TypeError: Cannot read properties of undefined (reading 'id')

Summary by cubic

Prevents a crash in the Stripe onSubscriptionUpdated webhook when a customer has no subscriptions in the database. The handler now safely ignores the event and logs a warning instead of throwing a TypeError.

  • Bug Fixes
    • Return early when no subscriptions are found for a customer, avoiding access to an undefined subscription.
    • Add a clear warning log and ignore the event, matching the existing behavior used for multiple non-active matches.
    • Applies to customer.subscription.updated events in the Stripe plugin.

Written for commit e8204361a8. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/8124 **Author:** [@JoDrm](https://github.com/JoDrm) **Created:** 2/24/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/stripe-webhook-empty-subscription-list` --- ### 📝 Commits (10+) - [`9dfbe0f`](https://github.com/better-auth/better-auth/commit/9dfbe0f40bffa6a55a698501101f43c012a4dead) feat(one-tap): add button mode for Google sign-in (#7482) - [`9145c92`](https://github.com/better-auth/better-auth/commit/9145c9233dcb714a77c7191db85ca9a597f416f9) refactor(stripe): centralize internal metadata management (#7561) - [`89e1043`](https://github.com/better-auth/better-auth/commit/89e1043d4e08378979af2a8957337e83a25022c7) chore: fix pnpm config (#7580) - [`136bd61`](https://github.com/better-auth/better-auth/commit/136bd61763783e6f31895ff7caaaf31883017560) chore(telemetry): move endpoint to env (#7578) - [`96a7ef5`](https://github.com/better-auth/better-auth/commit/96a7ef59703249f606e12174d5900498ff9208ac) fix: refresh `account_data` cookie when session is refreshed (#7576) - [`1088b1c`](https://github.com/better-auth/better-auth/commit/1088b1c7c162399cf72821e35be29c2905e9120d) docs: move errors content to reference section (#7581) - [`bad586a`](https://github.com/better-auth/better-auth/commit/bad586a512ec6ee7492fc021919ece40a1190801) docs: add better-auth-strapi community plugin (#7573) - [`10690f4`](https://github.com/better-auth/better-auth/commit/10690f4f3c05a7d9c0712caaf2ff0dddc45d2fa1) fix: log error when misconfigured (#7584) - [`8d6e8a1`](https://github.com/better-auth/better-auth/commit/8d6e8a1b59b5881cc48b297e53c70e44332ba122) docs: prevent content overflow (#7588) - [`fe64e65`](https://github.com/better-auth/better-auth/commit/fe64e659e2bd3db9d8b6e63e34400270e47fe808) docs: rewrite Convex integration content (#7527) ### 📊 Changes **1004 files changed** (+103697 additions, -31625 deletions) <details> <summary>View changed files</summary> ➕ `.claude/rules/release.md` (+123 -0) 📝 `.cspell/alt-languages.txt` (+9 -1) 📝 `.cspell/company-names.txt` (+2 -1) 📝 `.cspell/names.txt` (+22 -1) 📝 `.cspell/tech-terms.txt` (+9 -1) 📝 `.cspell/third-party.txt` (+4 -1) 📝 `.github/ISSUE_TEMPLATE/bug_report.yml` (+1 -1) ➕ `.github/actions/setup-playwright/action.yml` (+68 -0) ➖ `.github/workflows/adapter-tests.yml` (+0 -71) ➖ `.github/workflows/auto-cherry-pick-to-main.yml` (+0 -337) ➖ `.github/workflows/cherry-pick-to-main.yml` (+0 -325) 📝 `.github/workflows/ci.yml` (+26 -33) ➕ `.github/workflows/claude.yml` (+53 -0) 📝 `.github/workflows/e2e.yml` (+80 -36) 📝 `.github/workflows/preview.yml` (+7 -6) 📝 `.github/workflows/release.yml` (+9 -2) 📝 `.gitignore` (+2 -0) ➖ `.npmrc` (+0 -1) 📝 `.nvmrc` (+1 -1) ➕ `.postmortem/client-side-import-server.md` (+141 -0) _...and 80 more files_ </details> ### 📄 Description ## Bug `onSubscriptionUpdated` in the Stripe plugin crashes with `TypeError: Cannot read properties of undefined (reading 'id')` when a `customer.subscription.updated` webhook event is received for a customer that has no subscription records in the database. ## Root Cause In `packages/stripe/src/hooks.ts`, when the subscription lookup by `stripeSubscriptionId` fails, the code falls back to querying by `stripeCustomerId`. If the result is an empty array (`subs.length === 0`), the `else` branch assigns `subscription = subs[0]!` which is `undefined`. The subsequent `subscription.id` access then crashes. ```typescript // Before (line ~314) } else { subscription = subs[0]!; // undefined when subs is empty } // Later (line ~335) where: [{ field: "id", value: subscription.id }] // TypeError! ``` ## Fix Add an early return when `subs` is empty, consistent with the existing guard for `subs.length > 1` with no active subscription. ```typescript if (subs.length === 0) { ctx.context.logger.warn( `Stripe webhook warning: No subscription found for customerId: ${customerId}, ignoring event`, ); return; } ``` ## How to reproduce 1. Have a Stripe customer with no subscription records in the database (e.g. a customer who only made one-time payments) 2. Trigger a `customer.subscription.updated` webhook event for that customer 3. The webhook handler crashes with `TypeError: Cannot read properties of undefined (reading 'id')` <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Prevents a crash in the Stripe onSubscriptionUpdated webhook when a customer has no subscriptions in the database. The handler now safely ignores the event and logs a warning instead of throwing a TypeError. - **Bug Fixes** - Return early when no subscriptions are found for a customer, avoiding access to an undefined subscription. - Add a clear warning log and ignore the event, matching the existing behavior used for multiple non-active matches. - Applies to customer.subscription.updated events in the Stripe plugin. <sup>Written for commit e8204361a84cbae9077af27d5176f296375d89b0. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 10:20:51 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#16006