calcom/cal.diy · critical · NotFoundException

Zoom app not found

Error message

Zoom app not found

What it means

Thrown by ZoomVideoService.getZoomAppKeys when the ZOOM app's keys (parsed via zoomAppKeysSchema) lack a client_id. The app is fetched by appsRepository.getAppBySlug(ZOOM); a falsy client_id triggers NotFoundException (HTTP 404). Server-side configuration issue affecting any Zoom OAuth entry point.

Source

Thrown at apps/api/v2/src/modules/conferencing/services/zoom-video.service.ts:36

@Injectable()
export class ZoomVideoService {
  private logger = new Logger("ZoomVideoService");
  private redirectUri = `${this.config.get("api.url")}/conferencing/${ZOOM}/oauth/callback`;

  constructor(
    private readonly config: ConfigService,
    private readonly appsRepository: AppsRepository,
    private readonly credentialsRepository: CredentialsRepository
  ) {}

  async getZoomAppKeys() {
    const app = await this.appsRepository.getAppBySlug(ZOOM);

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

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

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

    return { client_id, client_secret };
  }

  async generateZoomAuthUrl(state: string) {
    const { client_id } = await this.getZoomAppKeys();

    const params = {
      response_type: "code",
      client_id,
      redirect_uri: this.redirectUri,
      state: state,
    };

View on GitHub (pinned to 176037d0af)

Solutions

  1. In the admin App Store, configure the Zoom app with its client_id (Server-to-Server or OAuth app ID from Zoom Marketplace).
  2. Verify the slug stored equals the ZOOM constant so getAppBySlug resolves correctly.
  3. Confirm keys match zoomAppKeysSchema (client_id + client_secret required).
Defensive patterns

Strategy: validation

Validate before calling

const app = await appsRepository.getAppBySlug(ZOOM);
const keys = zoomAppKeysSchema.safeParse(app?.keys);
if (!keys.success || !keys.data.client_id) {
  throw new Error('Zoom app misconfigured: missing client_id.');
}

Type guard

const hasZoomClientId = (k: unknown): k is { client_id: string; client_secret: string } =>
  typeof k === 'object' && k !== null && typeof (k as any).client_id === 'string' && !!(k as any).client_id;

Prevention

When it happens

Trigger: generateZoomAuthUrl or connectZoomApp invoked when the Zoom app row exists but its keys JSON has no usable client_id. The first `if (!client_id)` guard fires.

Common situations: Zoom app never configured in the App Store; app row present but client_id blank after a partial setup; wrong app slug; keys JSON shape changed but app not re-saved.

Related errors


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