calcom/cal.diy · error · NotFoundException

User with username ${input.username} not found

Error message

User with username ${input.username} not found

What it means

A NestJS NotFoundException (HTTP 404) thrown by SlotsInputService_2024_09_04.getEventType when the request resolves an event type by username + event-type slug. The usersRepository.findByUsername(input.username) lookup returned null, so no user matches the supplied username. The error echoes the offending username so you can identify the bad reference.

Source

Thrown at apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-input.service.ts:102

    const baseTransformation = await this.transformGetSlotsQuery(baseQuery);

    return {
      ...baseTransformation,
      routedTeamMemberIds: routedTeamMemberIds || null,
      skipContactOwner: skipContactOwner || false,
      teamMemberEmail: teamMemberEmail || null,
    };
  }

  private async getEventType(input: GetSlotsInput_2024_09_04) {
    if (input.type === ById_2024_09_04_type) {
      return this.eventTypeRepository.getEventTypeById(input.eventTypeId);
    }

    if (input.type === ByUsernameAndEventTypeSlug_2024_09_04_type) {
      const user = await this.getEventTypeUser(input);
      if (!user) {
        throw new NotFoundException(`User with username ${input.username} not found`);
      }
      return this.eventTypeRepository.getUserEventTypeBySlug(user.id, input.eventTypeSlug);
    }

    if (input.type === ByTeamSlugAndEventTypeSlug_2024_09_04_type) {
      const team = await this.getEventTypeTeam(input);
      if (!team) {
        throw new NotFoundException(`Team with slug ${input.teamSlug} not found`);
      }
      return this.teamsEventTypesRepository.getEventTypeByTeamIdAndSlug(team.id, input.eventTypeSlug);
    }

    return input.duration ? { ...dynamicEvent, length: input.duration } : dynamicEvent;
  }

  private async getEventTypeUser(input: ByUsernameAndEventTypeSlug_2024_09_04) {
    return await this.usersRepository.findByUsername(input.username);
  }

View on GitHub (pinned to 176037d0af)

Solutions

  1. Verify the username exists in the Cal.com app under /users or via the users API before calling slots.
  2. Confirm you are passing the `username` field (not email, not display name) and that it matches the user's profile slug exactly (case-sensitive).
  3. If the user belongs to an organization, pass the correct organizationSlug so the lookup hits the right tenant.
  4. Catch HTTP 404 in the client and surface a 'user not found' message to the end user with a prompt to re-check the link.

Example fix

// before
const res = await fetch(`/v2/slots?username=${email}&eventTypeSlug=30min`);

// after — use the actual username slug and validate first
const user = await calApi.getUserByUsername(username);
if (!user) throw new ClientError(`Unknown username: ${username}`);
const res = await fetch(`/v2/slots?username=${encodeURIComponent(user.username)}&eventTypeSlug=30min`);
Defensive patterns

Strategy: validation

Validate before calling

import { DateTime } from 'luxon';

function assertUsernameResolvable(username: unknown): string {
  if (typeof username !== 'string' || username.trim() === '') {
    throw new TypeError('username must be a non-empty string');
  }
  // usernames are slugs — reject emails / display names early
  if (/@\s|\s/.test(username)) {
    throw new TypeError('Pass the username slug, not an email or display name');
  }
  return username.trim();
}
// Optional: confirm via GET /v2/users or the app before slots
const username = assertUsernameResolvable(input.username);
const user = await cal.users.getByUsername(username);
if (!user) throw new ClientError(`User '${username}' not found`);

Type guard

function isByUsernameAndSlug(value: unknown): value is { username: string; eventTypeSlug: string } {
  return typeof value === 'object' && value !== null
    && typeof (value as any).username === 'string'
    && typeof (value as any).eventTypeSlug === 'string';
}

Try / catch

try {
  await cal.slots.list({ type: 'usernameAndEventTypeSlug', username, eventTypeSlug, start, end });
} catch (e) {
  if (e instanceof HttpError && e.statusCode === 404) {
    // user does not exist — re-prompt, don't retry blindly
    throw new UserFacingError('Booking link is invalid — user not found');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling GET /v2/slots/2024-09-04 with type === "usernameAndEventTypeSlug" where the `username` field does not match any user record (typo, deleted user, unverified account, wrong org scope, or username moved to an organization subdomain).

Common situations: Hardcoding a username in an integration that was later renamed or deleted; passing the user's email instead of their username; querying before the user finished sign-up; username lives under an org slug that was not supplied via organizationSlug.

Related errors


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