calcom/cal.diy · error · NotFoundException

Event type with id ${eventTypeId} not found

Error message

Event type with id ${eventTypeId} not found

What it means

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.

Source

Thrown at apps/api/v2/src/platform/event-types/event-types_2024_04_15/controllers/event-types.controller.ts:92

    const eventType = await this.eventTypesService.createUserEventType(user, body);

    return {
      status: SUCCESS_STATUS,
      data: eventType,
    };
  }

  @Get("/:eventTypeId")
  @Permissions([EVENT_TYPE_READ])
  @UseGuards(ApiAuthGuard)
  async getEventType(
    @Param("eventTypeId", ParseIntPipe) eventTypeId: number,
    @GetUser() user: UserWithProfile
  ): Promise<GetEventTypeOutput> {
    const eventType = await this.eventTypesService.getUserEventTypeForAtom(user, Number(eventTypeId));

    if (!eventType) {
      throw new NotFoundException(`Event type with id ${eventTypeId} not found`);
    }

    return {
      status: SUCCESS_STATUS,
      data: eventType,
    };
  }

  @Get("/")
  @Permissions([EVENT_TYPE_READ])
  @UseGuards(ApiAuthGuard)
  async getEventTypes(@GetUser() user: UserWithProfile): Promise<GetEventTypesOutput> {
    const eventTypes = await getEventTypesByViewer({
      id: user.id,
      profile: {
        upId: `usr-${user.id}`,
      },
    });

View on GitHub (pinned to 176037d0af)

Solutions

  1. Confirm the authenticated user owns the event type or is an admin of the owner's organization.
  2. List the user's event types via GET /v2/event-types and use an id from that response.
  3. Verify the access token / API key belongs to the event type's owner.
  4. If the user should have access, check their organization membership and role in the admin console.

Example fix

// before
const et = await api.get(`/v2/event-types/${someHardcodedId}`);
// after
const mine = (await api.get('/v2/event-types')).data;
const target = mine.find(e => e.slug === 'thirty-min');
if (!target) throw new Error('event type not owned by this user');
const et = await api.get(`/v2/event-types/${target.id}`);
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the authenticated user owns or can access the event type
const owned = (await api.get('/v2/event-types')).data ?? [];
if (!owned.some((e) => e.id === eventTypeId)) {
  throw new Error(`event type ${eventTypeId} not accessible to this user`);
}

Type guard

function isOwnedEventType(list: unknown, id: number): list is Array<{ id: number }> {
  return Array.isArray(list) && list.some((e) => typeof e === 'object' && e !== null && (e as any).id === id);
}

Try / catch

try {
  return await api.get(`/v2/event-types/${eventTypeId}`);
} catch (e) {
  if (e.response?.status === 404) {
    // could be not-found OR forbidden — prompt the user to re-authenticate or pick from their list
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/5df2b6a897d430ae. Report an issue: GitHub.