{"record":{"id":"e44e4e1457e5d93a","repo":"calcom/cal.diy","slug":"user-already-has-an-event-type-with-this-slug-e44e4e","errorCode":null,"errorMessage":"User already has an event type with this slug.","messagePattern":"User already has an event type with this slug\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/event-types/event-types_2024_06_14/services/event-types.service.ts","lineNumber":108,"sourceCode":"    const hasAccess = await this.eventTypeAccessService.userIsEventTypeAdminOrOwner(\n      authUser,\n      eventType as unknown as EventType\n    );\n\n    if (!hasAccess) {\n      return null;\n    }\n\n    return {\n      ownerId: eventType.userId ?? 0,\n      ...eventType,\n    };\n  }\n\n  async checkCanCreateEventType(userId: number, body: InputEventTransformed_2024_06_14) {\n    const existsWithSlug = await this.eventTypesRepository.getUserEventTypeBySlug(userId, body.slug);\n    if (existsWithSlug) {\n      throw new BadRequestException(\"User already has an event type with this slug.\");\n    }\n    await this.checkUserOwnsSchedule(userId, body.scheduleId);\n  }\n\n  checkHasUserAccessibleEmailBookingField(bookingFields: (SystemField | CustomField)[]) {\n    const emailField = bookingFields.find((field) => field.type === \"email\" && field.name === \"email\");\n    const isEmailFieldRequiredAndVisible = emailField?.required && !emailField?.hidden;\n    if (!isEmailFieldRequiredAndVisible) {\n      throw new BadRequestException(\n        \"checkIsEmailUserAccessible - Email booking field must be required and visible\"\n      );\n    }\n  }\n\n  async getEventTypeByUsernameAndSlug(params: {\n    username: string;\n    eventTypeSlug: string;\n    orgSlug?: string;","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/event-types/event-types_2024_06_14/services/event-types.service.ts#L90-L126","documentation":"Thrown by EventTypesService_2024_06_14.checkCanCreateEventType (POST /v2/event-types, cal-api-version 2024-06-14) when getUserEventTypeBySlug returns a row — the user already owns an event type with the requested slug. Slug uniqueness is enforced per user before any write occurs. Identical message to the 2024_04_15 service; both versions share this contract.","triggerScenarios":"POST /v2/event-types with a slug duplicating an existing one for the same user; retrying a successful create with the same slug; slug collision after a rename; importing event types without dedup.","commonSituations":"Network-retry of a succeeded create; deterministic slug generation from a title that already exists; migrating event types between users without changing the slug; frontend not refreshing after create.","solutions":["GET /v2/event-types (cal-api-version 2024-06-14) and confirm the slug is unused before POSTing.","Append a numeric suffix to the slug when the preferred one is taken.","If retrying after a possible success, list event types and PATCH the existing one instead of re-creating.","Derive slugs from a stable external id to make retries idempotent."],"exampleFix":"// before\nawait api.post('/v2/event-types', { slug: 'intro-call', ... }, { headers: { 'cal-api-version': '2024-06-14' } });\n// after\nconst mine = (await api.get('/v2/event-types', { headers: { 'cal-api-version': '2024-06-14' } })).data;\nif (mine.some(e => e.slug === 'intro-call')) throw new Error('slug taken');\nawait api.post('/v2/event-types', { slug: 'intro-call', ... }, { headers: { 'cal-api-version': '2024-06-14' } });","handlingStrategy":"validation","validationCode":"// Check slug uniqueness before create (2024_06_14)\nconst mine = (await api.get('/v2/event-types', { headers: { 'cal-api-version': '2024-06-14' } })).data ?? [];\nif (mine.some((e) => e.slug === body.slug)) {\n  throw new Error(`slug ${body.slug} already used by this user`);\n}","typeGuard":"function isSlugAvailable(list: unknown, slug: string): boolean {\n  return Array.isArray(list) && !list.some((e) => typeof e === 'object' && e !== null && (e as any).slug === slug);\n}","tryCatchPattern":"try {\n  await api.post('/v2/event-types', body, { headers: { 'cal-api-version': '2024-06-14' } });\n} catch (e) {\n  if (e.response?.status === 400 && e.response?.data?.message?.includes('slug')) {\n    // append suffix or switch to PATCH on the existing id\n  } else throw e;\n}","preventionTips":["Derive slugs from a stable external id for idempotent retries.","After a create timeout, list before retrying.","Keep a client-side cache of used slugs per user."],"tags":["nestjs","bad-request","event-types","uniqueness","cal-api-version"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}