{"record":{"id":"4246bc395cc96cc6","repo":"calcom/cal.diy","slug":"event-type-with-id-eventtypeid-does-not-exist-4246bc","errorCode":null,"errorMessage":"Event type with ID=${eventTypeId} does not exist.","messagePattern":"Event type with ID=(.+?) does not exist\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/platform/event-types/event-types_2024_06_14/services/event-types.service.ts","lineNumber":354,"sourceCode":"\n  async getUserToUpdateEvent(user: UserWithProfile) {\n    const profileId = this.usersService.getUserMainProfile(user)?.id || null;\n    const selectedCalendars = await this.selectedCalendarsRepository.getUserSelectedCalendars(user.id);\n    const eventTypeSelectedCalendars =\n      await this.selectedCalendarsRepository.getUserEventTypeSelectedCalendar(user.id);\n    return {\n      ...user,\n      locale: user.locale ?? \"en\",\n      profile: { id: profileId },\n      userLevelSelectedCalendars: selectedCalendars,\n      allSelectedCalendars: [...eventTypeSelectedCalendars, ...selectedCalendars],\n    };\n  }\n\n  async deleteEventType(eventTypeId: number, userId: number) {\n    const existingEventType = await this.eventTypesRepository.getEventTypeById(eventTypeId);\n    if (!existingEventType) {\n      throw new NotFoundException(`Event type with ID=${eventTypeId} does not exist.`);\n    }\n\n    this.checkUserOwnsEventType(userId, existingEventType);\n\n    return this.eventTypesRepository.deleteEventType(eventTypeId);\n  }\n\n  checkUserOwnsEventType(userId: number, eventType: Pick<EventType, \"id\" | \"userId\">) {\n    if (userId !== eventType.userId) {\n      throw new ForbiddenException(`User with ID=${userId} does not own event type with ID=${eventType.id}`);\n    }\n  }\n\n  async checkUserOwnsSchedule(userId: number, scheduleId: number | null | undefined) {\n    if (!scheduleId) {\n      return;\n    }\n","sourceCodeStart":336,"sourceCodeEnd":372,"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#L336-L372","documentation":"deleteEventType first calls getEventTypeById (by id only, not scoped to a user) and throws NotFoundException when that returns null. Ownership is checked separately afterward (see 424). So this specific throw fires only when the id does not exist at all.","triggerScenarios":"DELETE an event type id that was never created or was already deleted; double-delete from two clients; an id copied incorrectly.","commonSituations":"Idempotent delete flows where another client already removed the resource; retry of a delete after success; stale id from a cached list.","solutions":["Treat a 404 on DELETE as a no-op success for idempotency.","Confirm the id exists (and is owned) with a GET before deleting if you need a strict before-state.","Refresh the event-type list to discard stale ids before deleting."],"exampleFix":"// before\nawait api.deleteEventType(id); // throws 404 if already gone\n// after\ntry { await api.deleteEventType(id); }\ncatch (e) { if (e.status === 404) return { deleted: false, reason: 'already-absent' }; throw e; }","handlingStrategy":"try-catch","validationCode":"const et = await api.getEventTypeById(id);\nif (!et) return { deleted: false, reason: 'absent' };","typeGuard":"null","tryCatchPattern":"try { await api.deleteEventType(id); return { deleted: true }; }\ncatch (e) {\n  if (e.status === 404) return { deleted: false, reason: 'already-absent' };\n  throw e;\n}","preventionTips":["Treat 404 on DELETE as idempotent success.","Refresh id lists before delete operations.","Confirm ownership before delete to distinguish 403 from 404."],"tags":["not-found","delete","idempotency","event-types"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}