{"record":{"id":"3bf45962f5687235","repo":"calcom/cal.diy","slug":"event-type-not-found-3bf459","errorCode":null,"errorMessage":"Event Type not found","messagePattern":"Event Type not found","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/modules/slots/slots-2024-04-15/services/slots.service.ts","lineNumber":19,"sourceCode":"import { EventTypesRepository_2024_04_15 } from \"@/platform/event-types/event-types_2024_04_15/event-types.repository\";\nimport { SlotsRepository_2024_04_15 } from \"@/modules/slots/slots-2024-04-15/slots.repository\";\nimport { Injectable, NotFoundException } from \"@nestjs/common\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { ReserveSlotInput_2024_04_15 } from \"@calcom/platform-types\";\n\n@Injectable()\nexport class SlotsService_2024_04_15 {\n  constructor(\n    private readonly eventTypeRepo: EventTypesRepository_2024_04_15,\n    private readonly slotsRepo: SlotsRepository_2024_04_15\n  ) {}\n\n  async reserveSlot(input: ReserveSlotInput_2024_04_15, headerUid?: string) {\n    const uid = headerUid || uuid();\n    const eventType = await this.eventTypeRepo.getEventTypeWithSeats(input.eventTypeId);\n    if (!eventType) {\n      throw new NotFoundException(\"Event Type not found\");\n    }\n\n    let shouldReserveSlot = true;\n    if (eventType.seatsPerTimeSlot) {\n      const bookingWithAttendees = input.bookingUid\n        ? await this.slotsRepo.getBookingWithAttendees(input.bookingUid)\n        : undefined;\n      const bookingAttendeesLength = bookingWithAttendees?.attendees?.length;\n      if (bookingAttendeesLength) {\n        const seatsLeft = eventType.seatsPerTimeSlot - bookingAttendeesLength;\n        if (seatsLeft < 1) shouldReserveSlot = false;\n      } else {\n        shouldReserveSlot = false;\n      }\n    }\n\n    if (eventType && shouldReserveSlot && !input._isDryRun) {\n      await Promise.all(","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/slots/slots-2024-04-15/services/slots.service.ts#L1-L37","documentation":"NotFoundException (HTTP 404) thrown by SlotsService_2024_04_15.reserveSlot() when eventTypeRepo.getEventTypeWithSeats(input.eventTypeId) returns null. Reserve-slot (seated-event booking hold) requires an existing event type configured for seats; a missing or inaccessible event type id is rejected before any seat accounting runs.","triggerScenarios":"POST /v2/slots/2024-04-15/{eventTypeId}/reserve (or the reserve-slot input path) with an eventTypeId that does not exist, was deleted, or is outside the caller's scope; reserving a slot for a non-seated event type id that was removed.","commonSituations":"Stale eventTypeId held in the client after the event type was deleted; deep link to a seated event that no longer exists; race between deletion and a reserve call; cross-org eventTypeId leak.","solutions":["Re-fetch the event type before attempting to reserve; if it 404s, refresh the user's event-type list.","Capture the eventTypeId at booking-start time and fail the flow gracefully if the event type disappears.","Ensure the client only shows currently-available seated event types for the reserve action."],"exampleFix":"// before\nawait api.reserveSlot({ eventTypeId: cachedId, slotUid });\n// after — validate existence first\nconst et = await api.getEventType(cachedId).catch(() => null);\nif (!et) { refreshEventTypes(); return; }\nawait api.reserveSlot({ eventTypeId: cachedId, slotUid });","handlingStrategy":"try-catch","validationCode":"async function reserveSlotGuarded(eventTypeId: number, input: ReserveInput) {\n  const et = await api.getEventTypeWithSeats(eventTypeId).catch(() => null);\n  if (!et) throw new Error(`Event type ${eventTypeId} not found`);\n  return api.reserveSlot({ ...input, eventTypeId });\n}","typeGuard":"const eventTypeWithSeatsExists = async (eventTypeId: number): Promise<boolean> =>\n  Boolean(await api.getEventTypeWithSeats(eventTypeId).catch(() => null));","tryCatchPattern":"try { await api.reserveSlot({ eventTypeId, slotUid }); }\ncatch (e) { if (e.status === 404) { refreshEventTypes(); } else throw e; }","preventionTips":["Re-fetch the seated event type before reserving.","Invalidate cached eventTypeId when the event type list changes.","Only offer the reserve action for currently-available seated event types."],"tags":["slots","event-type","not-found","reserve-slot","nestjs"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}