{"record":{"id":"b0e79ca59f8b7772","repo":"calcom/cal.diy","slug":"webhook-with-this-subscriber-url-already-exists-fo-b0e79c","errorCode":null,"errorMessage":"Webhook with this subscriber url already exists for this oAuth client","messagePattern":"Webhook with this subscriber url already exists for this oAuth client","errorType":"http","errorClass":"ConflictException","httpStatus":409,"severity":"error","filePath":"apps/api/v2/src/modules/webhooks/services/oauth-clients-webhooks.service.ts","lineNumber":18,"sourceCode":"import { PipedInputWebhookType } from \"@/modules/webhooks/pipes/WebhookInputPipe\";\nimport { validateWebhookUrl } from \"@/modules/webhooks/utils/validate-webhook-url\";\nimport { WebhooksRepository } from \"@/modules/webhooks/webhooks.repository\";\nimport { ConflictException, Injectable } from \"@nestjs/common\";\n\n@Injectable()\nexport class OAuthClientWebhooksService {\n  constructor(private readonly webhooksRepository: WebhooksRepository) {}\n\n  async createOAuthClientWebhook(platformOAuthClientId: string, body: PipedInputWebhookType) {\n    validateWebhookUrl(body.subscriberUrl);\n\n    const existingWebhook = await this.webhooksRepository.getOAuthClientWebhookByUrl(\n      platformOAuthClientId,\n      body.subscriberUrl\n    );\n    if (existingWebhook) {\n      throw new ConflictException(\"Webhook with this subscriber url already exists for this oAuth client\");\n    }\n\n    return this.webhooksRepository.createOAuthClientWebhook(platformOAuthClientId, {\n      ...body,\n      payloadTemplate: body.payloadTemplate ?? null,\n      secret: body.secret ?? null,\n    });\n  }\n\n  async getOAuthClientWebhooksPaginated(platformOAuthClientId: string, skip: number, take: number) {\n    return this.webhooksRepository.getOAuthClientWebhooksPaginated(platformOAuthClientId, skip, take);\n  }\n\n  async deleteAllOAuthClientWebhooks(platformOAuthClientId: string): Promise<{ count: number }> {\n    return this.webhooksRepository.deleteAllOAuthClientWebhooks(platformOAuthClientId);\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/webhooks/services/oauth-clients-webhooks.service.ts#L1-L36","documentation":"OAuthClientWebhooksService.createOAuthClientWebhook queries getOAuthClientWebhookByUrl(platformOAuthClientId, subscriberUrl); if a row already exists it throws ConflictException (HTTP 409). The (platformOAuthClientId, subscriberUrl) pair is unique per OAuth client.","triggerScenarios":"POSTing a webhook for an OAuth client whose subscriberUrl is already registered for that same client. Unlike event-type/user webhooks, there is no DELEGATION_CREDENTIAL_ERROR guard here — only the duplicate check.","commonSituations":"Re-registering a callback after a transient failure that actually succeeded; two OAuth flows for the same client using one callback URL; replayed webhooks.","solutions":["List the client's existing webhooks and check the subscriberUrl before creating.","Make subscriber URLs unique per registration.","Handle 409 as success-when-duplicate."],"exampleFix":"// before\nawait api.createOAuthClientWebhook(clientId, { subscriberUrl, ... });\n// after\nconst list = await api.listOAuthClientWebhooks(clientId);\nif (list.find(w => w.subscriberUrl === subscriberUrl)) return;\nawait api.createOAuthClientWebhook(clientId, { subscriberUrl, ... });","handlingStrategy":"validation","validationCode":"async function createIfMissingOAuthClient(api, clientId, body) {\n  const list = await api.getOAuthClientWebhooksPaginated(clientId, 0, 1000);\n  if (list.find(w => w.subscriberUrl === body.subscriberUrl)) return;\n  return api.createOAuthClientWebhook(clientId, body);\n}","typeGuard":"const isDuplicateUrl = (list: { subscriberUrl: string }[], url: string): boolean =>\n  list.some(w => w.subscriberUrl === url);","tryCatchPattern":"try { await api.createOAuthClientWebhook(clientId, body); }\ncatch (e) { if (e.status === 409) return; else throw e; }","preventionTips":["Use distinct callback URLs per OAuth client registration.","Deduplicate retries by subscriberUrl.","Idempotently absorb 409 responses."],"tags":["webhooks","conflict","duplicate","oauth"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}