calcom/cal.diy · error · NotFoundException

Team with slug not found

Error message

Team with slug ${input.teamSlug} not found

What it means

A NestJS NotFoundException (HTTP 404) thrown by SlotsInputService_2024_09_04.getEventType when resolving an event type by team slug + event-type slug. teamsRepository.findTeamBySlug(input.teamSlug) returned null, meaning no team matches the given slug. The thrown message includes the bad slug.

Solutions

  1. Fetch the team list via the teams API and confirm the exact team slug before requesting slots.
  2. Trim whitespace and URL-decode the teamSlug before sending it.
  3. If the team belongs to an organization, pass organizationSlug so the slug resolves in the correct scope.
  4. Map the 404 to a user-facing 'team not found' error and re-prompt for the booking link.

Example fix

// before
fetch(`/v2/slots?teamSlug=${teamName}&eventTypeSlug=group`)

// after
const team = await calApi.teams.getBySlug(teamSlug.trim().toLowerCase());
if (!team) throw new ClientError(`Team '${teamSlug}' does not exist`);
fetch(`/v2/slots?teamSlug=${encodeURIComponent(team.slug)}&eventTypeSlug=group`);
Defensive patterns

Strategy: validation

Validate before calling

function normalizeTeamSlug(slug: unknown): string {
  if (typeof slug !== 'string' || slug.trim() === '') {
    throw new TypeError('teamSlug must be a non-empty string');
  }
  return slug.trim().toLowerCase();
}
const teamSlug = normalizeTeamSlug(input.teamSlug);
const team = await cal.teams.getBySlug(teamSlug);
if (!team) throw new ClientError(`Team '${teamSlug}' not found`);

Type guard

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

Try / catch

try {
  await cal.slots.list({ type: 'teamSlugAndEventTypeSlug', teamSlug, eventTypeSlug, start, end });
} catch (e) {
  if (e instanceof HttpError && e.statusCode === 404) {
    throw new UserFacingError('Team booking link is invalid');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling GET /v2/slots/2024-09-04 with type === "teamSlugAndEventTypeSlug" where `teamSlug` does not correspond to any team (typo, renamed team, team is part of an org and slug scoping is off, slug has trailing whitespace).

Common situations: Stale configuration referencing a renamed team; copying a slug from the UI that includes leading/trailing spaces or the display name instead of the slug; org teams requiring an organizationSlug qualifier.

Related errors


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

Appendix: source

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

  }

  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);
  }

  private async getEventTypeTeam(input: ByTeamSlugAndEventTypeSlug_2024_09_04) {
    return await this.teamsRepository.findTeamBySlug(input.teamSlug);
  }

  private adjustStartTime(startTime: string) {
    let dateTime = DateTime.fromISO(startTime, { zone: "utc" });
    if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0) {

View on GitHub (pinned to 176037d0af)