{"record":{"id":"5df2b6a897d430ae","repo":"calcom/cal.diy","slug":"event-type-with-id-eventtypeid-not-found-5df2b6","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/controllers/event-types.controller.ts","lineNumber":92,"sourceCode":"    const eventType = await this.eventTypesService.createUserEventType(user, body);\n\n    return {\n      status: SUCCESS_STATUS,\n      data: eventType,\n    };\n  }\n\n  @Get(\"/:eventTypeId\")\n  @Permissions([EVENT_TYPE_READ])\n  @UseGuards(ApiAuthGuard)\n  async getEventType(\n    @Param(\"eventTypeId\", ParseIntPipe) eventTypeId: number,\n    @GetUser() user: UserWithProfile\n  ): Promise<GetEventTypeOutput> {\n    const eventType = await this.eventTypesService.getUserEventTypeForAtom(user, Number(eventTypeId));\n\n    if (!eventType) {\n      throw new NotFoundException(`Event type with id ${eventTypeId} not found`);\n    }\n\n    return {\n      status: SUCCESS_STATUS,\n      data: eventType,\n    };\n  }\n\n  @Get(\"/\")\n  @Permissions([EVENT_TYPE_READ])\n  @UseGuards(ApiAuthGuard)\n  async getEventTypes(@GetUser() user: UserWithProfile): Promise<GetEventTypesOutput> {\n    const eventTypes = await getEventTypesByViewer({\n      id: user.id,\n      profile: {\n        upId: `usr-${user.id}`,\n      },\n    });","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/event-types/event-types_2024_04_15/controllers/event-types.controller.ts#L74-L110","documentation":"Thrown by EventTypesController_2024_04_15.getEventType (GET /v2/event-types/:eventTypeId) when eventTypesService.getUserEventTypeForAtom returns null. Null means the event type does not exist, the user is not the owner, and the user is not an organization admin who can scope to it. The controller cannot distinguish 'not found' from 'forbidden', so it returns 404 for both to avoid leaking existence.","triggerScenarios":"GET /v2/event-types/999 where 999 does not exist; GET for an event type owned by another user where the authenticated user is not an org admin; the eventTypeId is valid but belongs to a different organization; ParseIntPipe already rejected non-numeric path params upstream.","commonSituations":"Hardcoding an eventTypeId from a different environment (dev vs prod); using an access token scoped to user A while requesting user B's event type; the event type was deleted between sessions; org membership not yet provisioned for the user.","solutions":["Confirm the authenticated user owns the event type or is an admin of the owner's organization.","List the user's event types via GET /v2/event-types and use an id from that response.","Verify the access token / API key belongs to the event type's owner.","If the user should have access, check their organization membership and role in the admin console."],"exampleFix":"// before\nconst et = await api.get(`/v2/event-types/${someHardcodedId}`);\n// after\nconst mine = (await api.get('/v2/event-types')).data;\nconst target = mine.find(e => e.slug === 'thirty-min');\nif (!target) throw new Error('event type not owned by this user');\nconst et = await api.get(`/v2/event-types/${target.id}`);","handlingStrategy":"validation","validationCode":"// Confirm the authenticated user owns or can access the event type\nconst owned = (await api.get('/v2/event-types')).data ?? [];\nif (!owned.some((e) => e.id === eventTypeId)) {\n  throw new Error(`event type ${eventTypeId} not accessible to this user`);\n}","typeGuard":"function isOwnedEventType(list: unknown, id: number): list is Array<{ id: number }> {\n  return Array.isArray(list) && list.some((e) => typeof e === 'object' && e !== null && (e as any).id === id);\n}","tryCatchPattern":"try {\n  return await api.get(`/v2/event-types/${eventTypeId}`);\n} catch (e) {\n  if (e.response?.status === 404) {\n    // could be not-found OR forbidden — prompt the user to re-authenticate or pick from their list\n  } else throw e;\n}","preventionTips":["Always source eventTypeId from the authenticated user's own GET /v2/event-types response.","Rotate access tokens when a user's org membership changes.","Treat 404 on a known-existing id as a probable authorization issue."],"tags":["nestjs","not-found","event-types","authorization","rest-api"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}