{"record":{"id":"4a7cb2862f44009f","repo":"calcom/cal.diy","slug":"event-type-with-id-eventtypeid-not-found-4a7cb2","errorCode":null,"errorMessage":"Event type with id ${eventTypeId} not found","messagePattern":"Event type with id (.+?) not found","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/platform/event-types/event-types_2024_04_15/services/event-types.service.ts","lineNumber":160,"sourceCode":"        type: BaseField.email,\n        editable: Editable.systemButOptional,\n      });\n    }\n\n    await updateEventType({\n      input: { id: eventTypeId, ...body, bookingFields },\n      ctx: {\n        user: eventTypeUser,\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-ignore\n        prisma: this.dbWrite.prisma,\n      },\n    });\n\n    const eventType = await this.getUserEventTypeForAtom(user, eventTypeId);\n\n    if (!eventType) {\n      throw new NotFoundException(`Event type with id ${eventTypeId} not found`);\n    }\n\n    return eventType.eventType;\n  }\n\n  async checkCanUpdateEventType(userId: number, eventTypeId: number) {\n    const existingEventType = await this.getUserEventType(userId, eventTypeId);\n    if (!existingEventType) {\n      throw new NotFoundException(`Event type with id ${eventTypeId} not found`);\n    }\n    this.checkUserOwnsEventType(userId, existingEventType);\n  }\n\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);","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/event-types/event-types_2024_04_15/services/event-types.service.ts#L142-L178","documentation":"Thrown by EventTypesService_2024_04_15.updateEventType (PATCH /v2/event-types/:eventTypeId) after a successful updateEventType library call, when the subsequent getUserEventTypeForAtom returns null. This is a post-update consistency check: the row was updated but can no longer be read as belonging to the authenticated user — a race or ownership-shift condition.","triggerScenarios":"PATCH succeeds, but between the update and the re-read the event type is deleted by another session, transferred to a different user, or the authenticated user's org admin status is revoked; the update silently nullified userId; a transaction isolation issue where the read replica lags behind the writer.","commonSituations":"Two admin sessions editing concurrently — one deletes while the other patches; org membership changes mid-request; read-replica lag in a distributed DB; a bug in updateEventType that clears the userId field.","solutions":["Retry the PATCH once after a short delay if you suspect read-replica lag.","Confirm no concurrent delete is running on the same eventTypeId.","Verify the authenticated user still owns the event type (or is still an org admin) via GET /v2/event-types/:eventTypeId.","If reproducible, inspect the updateEventType library call for a field that inadvertently resets userId."],"exampleFix":"// before\nconst updated = await api.patch(`/v2/event-types/${id}`, body);\n// after\nawait api.patch(`/v2/event-types/${id}`, body);\nlet updated;\ntry {\n  updated = await api.get(`/v2/event-types/${id}`);\n} catch (e) {\n  if (e.response?.status === 404) throw new Error('event type disappeared after update; possible concurrent delete');\n  throw e;\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  return await api.patch(`/v2/event-types/${id}`, body);\n} catch (e) {\n  if (e.response?.status === 404) {\n    // post-update read failure — retry once after a short delay\n    await new Promise((r) => setTimeout(r, 200));\n    return await api.get(`/v2/event-types/${id}`);\n  }\n  throw e;\n}","preventionTips":["Avoid concurrent PATCH and DELETE on the same eventTypeId.","After PATCH, fall back to a GET to confirm the update rather than trusting the PATCH response alone.","If using read replicas, route post-write reads to the primary or accept eventual consistency with retries."],"tags":["nestjs","not-found","event-types","race-condition","rest-api"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}