toeverything/AFFiNE · error · SubscriptionAlreadyExists

subscription_already_exists

subscription_already_exists

Error message

You have already subscribed to the ${plan} plan.

What it means

checkout throws SubscriptionAlreadyExists when the user already holds an active subscription whose recurring interval cannot be combined with the requested plan, preventing duplicate or conflicting subscriptions.

Source

Thrown at packages/backend/server/src/plugins/payment/manager/user.ts:115

      lookupKey.variant !== null
    ) {
      throw new InvalidCheckoutParameters();
    }

    const active = await this.getVisibleSubscription({
      plan: lookupKey.plan,
      userId: user.id,
    });
    await this.assertNoActiveLocalEntitlement(user.id, lookupKey);
    if (active?.provider === 'revenuecat') {
      throw new ManagedByAppStoreOrPlay();
    }

    if (
      active &&
      !this.canCheckoutWithExistingSubscription(active.recurring, lookupKey)
    ) {
      throw new SubscriptionAlreadyExists({ plan: lookupKey.plan });
    }

    const customer = await this.getOrCreateCustomer(user.id);
    const stripeSubscriptions = await this.stripe.subscriptions.list({
      customer: customer.stripeCustomerId,
      status: 'all',
    });
    this.assertNoActiveStripeSubscription(stripeSubscriptions.data, lookupKey);
    await this.assertNoActiveRevenueCatSubscription(user.id, lookupKey);
    const price = await this.getPrice(lookupKey);

    if (!price || !(await this.isPriceAvailable(price))) {
      throw new SubscriptionPlanNotFound({
        plan: lookupKey.plan,
        recurring: lookupKey.recurring,
      });
    }

View on GitHub (pinned to b4c8548c09)

Solutions

  1. No action needed: the account already has an active subscription to this plan.
  2. To change plans, cancel the current subscription first or use a plan-change flow.
  3. Refresh the subscription state in the client to reflect the existing subscription.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/backend/server/src/plugins/payment/manager/user.ts:115 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/975c26bcc503927e. Report an issue: GitHub.