calcom/cal.diy · error · NotFoundException

Stripe app not found

Error message

Stripe app not found

What it means

Thrown by StripeService.getStripeAppKeys after it loads the 'stripe' app by slug and parses app.keys with stripeKeysResponseSchema. The schema requires client_id to be a non-empty string starting with 'ca_', so in practice a malformed client_id throws a ZodError first; this NotFoundException guard is defense-in-depth for the case where parsing somehow yields an empty client_id. Either way the root cause is a missing/misconfigured Stripe app key.

Source

Thrown at apps/api/v2/src/modules/stripe/stripe.service.ts:90

      },
      redirect_uri: this.redirectUri,
      state: JSON.stringify(state),
    };

    const params = z.record(z.any()).parse(stripeConnectParams);
    const query = stringify(params);
    const url = `https://connect.stripe.com/oauth/authorize?${query}`;

    return url;
  }

  async getStripeAppKeys() {
    const app = await this.appsRepository.getAppBySlug("stripe");

    const { client_id, client_secret } = stripeKeysResponseSchema.parse(app?.keys);

    if (!client_id) {
      throw new NotFoundException("Stripe app not found");
    }

    if (!client_secret) {
      throw new NotFoundException("Stripe app not found");
    }

    return { client_id, client_secret };
  }

  async saveStripeAccount(state: OAuthCallbackState, code: string, userId: number): Promise<{ url: string }> {
    if (!userId) {
      throw new UnauthorizedException("Invalid Access token.");
    }

    const response = await stripeInstance.oauth.token({
      grant_type: "authorization_code",
      code: code?.toString(),
    });

View on GitHub (pinned to 176037d0af)

Solutions

  1. Install the Stripe app from the app store and set a full key set: client_id (ca_...), client_secret (sk_...), public_key (pk_...), webhook_secret (whsec_).
  2. Verify in the database/apps config that the 'stripe' slug exists and its keys JSON parses with all four prefixed values.
  3. Confirm you are pointed at the environment where the Stripe app is configured.
Defensive patterns

Strategy: validation

Validate before calling

// Validate Stripe app keys shape before any Stripe operation.
import { z } from 'zod';
const keysSchema = z.object({
  client_id: z.string().startsWith('ca_').min(1),
  client_secret: z.string().startsWith('sk_').min(1),
  public_key: z.string().startsWith('pk_').min(1),
  webhook_secret: z.string().startsWith('whsec_').min(1),
});
function stripeKeysConfigured(app): boolean {
  return keysSchema.safeParse(app?.keys).success;
}

Type guard

function hasStripeClientId(keys: unknown): boolean {
  return typeof (keys as any)?.client_id === 'string' && (keys as any).client_id.startsWith('ca_');
}

Try / catch

try {
  await api.stripeRedirect();
} catch (e) {
  if (e.status === 404 && /Stripe app not found/.test(e.message)) {
    surfaceToAdmin('Configure the Stripe app (client_id, client_secret, public_key, webhook_secret).');
  } else throw e;
}

Prevention

When it happens

Trigger: Any Stripe operation that needs the app keys (redirect, save, checkout) when the Stripe app is not installed or its keys JSON lacks a valid client_id (e.g. app.keys is null, or client_id is empty).

Common situations: The Stripe app was never installed in this environment. The app's keys were only partially configured (client_secret set but client_id blank). The app record's keys JSON was corrupted or migrated incorrectly. A staging env points at an unseeded database.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/be038103640042b5. Report an issue: GitHub.