calcom/cal.diy · error · ConflictException

Webhook with this subscriber url already exists for this use

Error message

Webhook with this subscriber url already exists for this user

What it means

UserWebhooksService.createUserWebhook calls getUserWebhookByUrl(userId, subscriberUrl); if a row exists for that user+URL it throws ConflictException (HTTP 409). The (userId, subscriberUrl) pair is unique.

Source

Thrown at apps/api/v2/src/modules/webhooks/services/user-webhooks.service.ts:23

import { WebhookTriggerEvents } from "@calcom/prisma/enums";

@Injectable()
export class UserWebhooksService {
  constructor(private readonly webhooksRepository: WebhooksRepository) {}

  async createUserWebhook(userId: number, body: PipedInputWebhookType) {
    validateWebhookUrl(body.subscriberUrl);

    if (body.eventTriggers.includes(WebhookTriggerEvents.DELEGATION_CREDENTIAL_ERROR)) {
      throw new BadRequestException(
        "DELEGATION_CREDENTIAL_ERROR trigger is only available for organization webhooks"
      );
    }

    const existingWebhook = await this.webhooksRepository.getUserWebhookByUrl(userId, body.subscriberUrl);
    if (existingWebhook) {
      throw new ConflictException("Webhook with this subscriber url already exists for this user");
    }

    return this.webhooksRepository.createUserWebhook(userId, {
      ...body,
      payloadTemplate: body.payloadTemplate ?? null,
      secret: body.secret ?? null,
    });
  }

  async getUserWebhooksPaginated(userId: number, skip: number, take: number) {
    return this.webhooksRepository.getUserWebhooksPaginated(userId, skip, take);
  }
}

View on GitHub (pinned to 176037d0af)

Solutions

  1. List the user's webhooks and check subscriberUrl before creating.
  2. Use unique subscriber URLs per webhook.
  3. Handle 409 as 'already registered' idempotently.

Example fix

// before
await api.createUserWebhook(userId, { subscriberUrl, ... });
// after
const list = await api.listUserWebhooks(userId);
if (list.find(w => w.subscriberUrl === subscriberUrl)) return;
await api.createUserWebhook(userId, { subscriberUrl, ... });
Defensive patterns

Strategy: validation

Validate before calling

async function createIfMissingUser(api, userId, body) {
  const list = await api.getUserWebhooksPaginated(userId, 0, 1000);
  if (list.find(w => w.subscriberUrl === body.subscriberUrl)) return;
  return api.createUserWebhook(userId, body);
}

Type guard

const isDuplicateUrl = (list: { subscriberUrl: string }[], url: string): boolean =>
  list.some(w => w.subscriberUrl === url);

Try / catch

try { await api.createUserWebhook(userId, body); }
catch (e) { if (e.status === 409) return; else throw e; }

Prevention

When it happens

Trigger: POSTing a user webhook with a subscriberUrl already registered for the same userId.

Common situations: Retry after a successful create; single callback endpoint reused across integrations for one user; dev URL reuse.

Related errors


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