calcom/cal.diy · error · NotFoundException

User with id=${newUserId} was not found in the database

Error message

User with id=${newUserId} was not found in the database

What it means

Thrown by reassignBookingToUser after permission checks pass, when usersRepository.findByIdWithProfile(newUserId) returns null. NestJS NotFoundException (HTTP 404) - the target user id supplied in the request body does not exist in the database.

Source

Thrown at apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts:1078

    }
    if (!booking.eventType) {
      throw new BadRequestException(
        `Event type with id=${booking.eventTypeId} was not found in the database`
      );
    }

    const isAllowed = await this.eventTypeAccessService.userIsEventTypeAdminOrOwner(
      reassignedByUser,
      booking.eventType
    );

    if (!isAllowed) {
      throw new ForbiddenException(BOOKING_REASSIGN_PERMISSION_ERROR);
    }

    const user = await this.usersRepository.findByIdWithProfile(newUserId);
    if (!user) {
      throw new NotFoundException(`User with id=${newUserId} was not found in the database`);
    }

    const platformClientParams = booking.eventTypeId
      ? await this.platformBookingsService.getOAuthClientParams(booking.eventTypeId)
      : undefined;

    const emailsEnabled = platformClientParams ? platformClientParams.arePlatformEmailsEnabled : true;

    const profile = this.usersService.getUserMainProfile(user);

    try {
      await roundRobinManualReassignment({
        bookingId: booking.id,
        newUserId,
        orgId: profile?.organizationId || null,
        reassignReason: body.reason,
        reassignedById: reassignedByUser.id,
        emailsEnabled,

View on GitHub (pinned to 176037d0af)

Solutions

  1. Fetch the booking's hosts via GET /v2/bookings/{uid} and select the newUserId from the returned host list.
  2. Validate the user exists with GET /v2/users or the users endpoint before reassigning.
  3. Ensure the id is the numeric primary key, not a uuid or email.
  4. Confirm the user belongs to the same organization as the event type.

Example fix

// before
await apiClient.post(`/v2/bookings/${uid}/reassign-to-user`, { userId: candidateId });

// after
const booking = await apiClient.get(`/v2/bookings/${uid}`).then(r => r.data);
const hostIds = (booking.hosts ?? []).map(h => h.id);
if (!hostIds.includes(candidateId)) throw new Error(`${candidateId} is not a host of booking ${uid}`);
await apiClient.post(`/v2/bookings/${uid}/reassign-to-user`, { userId: candidateId });
Defensive patterns

Strategy: validation

Validate before calling

// Only pass a userId that is a real, in-org host of the booking
const booking = await apiClient.get(`/v2/bookings/${uid}`).then(r => r.data);
const hostIds = (booking.hosts ?? []).map(h => h.id);
if (!hostIds.includes(newUserId)) {
  throw new Error(`User ${newUserId} is not a host of booking ${uid}`);
}

Type guard

function isKnownHost(userId: number, booking: { hosts?: Array<{ id: number }> }): boolean {
  return (booking.hosts ?? []).some(h => h.id === userId);
}

Try / catch

try {
  await apiClient.post(`/v2/bookings/${uid}/reassign-to-user`, { userId: newUserId });
} catch (err) {
  if (err.response?.status === 404 && /User with id=.*was not found/i.test(err.response?.data?.message ?? '')) {
    throw new UserMissingError(newUserId);
  }
  throw err;
}

Prevention

When it happens

Trigger: POST reassign-to-user with a newUserId that is mistyped, belongs to another org, or was deleted; passing the user's uuid instead of the numeric id.

Common situations: Confusing numeric user id with uuid/username; referencing a user from a different environment; deactivated/deleted users; off-by-one or copy errors in the id.

Related errors


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