calcom/cal.diy · error · NotFoundException

Team with id ${teamId} not found

Error message

Team with id ${teamId} not found

What it means

Thrown by EventTypesAtomService.getTeamSlug when prisma.team.findUnique returns null or a team record without a slug for the given teamId. This private method is called from both getPublicEventTypeForAtoms (to resolve org or team slug) and is a prerequisite for building the public event URL. A team without a slug cannot be addressed by a URL path, so the lookup is aborted with NotFoundException (HTTP 404).

Source

Thrown at apps/api/v2/src/modules/atoms/services/event-types-atom.service.ts:83

  constructor(
    private readonly membershipsRepository: MembershipsRepository,
    private readonly credentialsRepository: CredentialsRepository,
    private readonly atomsRepository: AtomsRepository,
    private readonly usersService: UsersService,
    private readonly dbWrite: PrismaWriteService,
    private readonly dbRead: PrismaReadService,
    private readonly eventTypeService: EventTypesService_2024_06_14,
    private readonly usersRepository: UsersRepository
  ) {}

  private async getTeamSlug(teamId: number): Promise<string> {
    const team = await this.dbRead.prisma.team.findUnique({
      where: { id: teamId },
      select: { slug: true },
    });

    if (!team?.slug) {
      throw new NotFoundException(`Team with id ${teamId} not found`);
    }
    return team.slug;
  }

  async getUserEventType(user: UserWithProfile, eventTypeId: number) {
    const organizationId = this.usersService.getUserMainOrgId(user);

    const isUserOrganizationAdmin = organizationId
      ? await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId)
      : false;

    const eventType = await getEventTypeById({
      currentOrganizationId: this.usersService.getUserMainOrgId(user),
      eventTypeId,
      userId: user.id,
      userLocale: user.locale ?? "en",
      prisma: this.dbRead.prisma as unknown as PrismaClient,
      isUserOrganizationAdmin,

View on GitHub (pinned to 176037d0af)

Solutions

  1. Verify the teamId exists in the team table and has a non-null slug before calling the endpoint.
  2. If the team exists but has no slug, set one via the team settings UI or database update.
  3. Clear stale team references from client-side caches or configuration.

Example fix

// before: passing unverified teamId
const event = await atomsApi.getPublicEventType({
  eventSlug: '30min',
  isTeamEvent: true,
  teamId: possiblyDeletedTeamId
});

// after: validate team existence first
const team = await api.get(`/v2/teams/${teamId}`);
if (!team?.slug) {
  throw new Error(`Team ${teamId} has no slug; configure it in team settings.`);
}
const event = await atomsApi.getPublicEventType({
  eventSlug: '30min',
  isTeamEvent: true,
  teamId: team.id
});
Defensive patterns

Strategy: validation

Validate before calling

// Verify team exists and has a slug before using it
const verifyTeamSlug = async (api: ApiClient, teamId: number): Promise<string> => {
  const team = await api.get(`/v2/teams/${teamId}`);
  if (!team?.slug) {
    throw new Error(`Team ${teamId} has no slug; set one in team settings before using it for event lookups.`);
  }
  return team.slug;
};

Type guard

interface TeamWithSlug { id: number; slug: string; }
const hasSlug = (team: { slug?: string | null } | null): team is TeamWithSlug =>
  team !== null && typeof team.slug === 'string' && team.slug.length > 0;

Try / catch

// Gracefully handle missing team/slug
try {
  const event = await atomsApi.getPublicEventType({
    eventSlug,
    isTeamEvent: true,
    teamId
  });
} catch (err: any) {
  if (err?.response?.status === 404 && err?.response?.data?.message?.includes('Team with id')) {
    console.error(`Team ${teamId} not found or has no slug. Verify the team exists.`);
    // Fall back to user event or prompt user to select a valid team
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling getPublicEventTypeForAtoms with an orgId or teamId that doesn't exist in the team table. The team exists but has a null slug (e.g. it was created but slug assignment failed, or it's a newly created team that hasn't been fully configured). The teamId comes from a stale reference (team was deleted or merged).

Common situations: Frontend passing an orgId from a cached dropdown that references a deleted team. A team in the DB with slug=null because it was created via an import or migration that didn't populate the slug. Race condition: team is being created concurrently and the event-type request arrives before slug assignment completes.

Related errors


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