{"record":{"id":"6ca3092afdf90ba9","repo":"calcom/cal.diy","slug":"team-with-id-teamid-not-found","errorCode":null,"errorMessage":"Team with id ${teamId} not found","messagePattern":"Team with id (.+?) not found","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/modules/atoms/services/event-types-atom.service.ts","lineNumber":83,"sourceCode":"  constructor(\n    private readonly membershipsRepository: MembershipsRepository,\n    private readonly credentialsRepository: CredentialsRepository,\n    private readonly atomsRepository: AtomsRepository,\n    private readonly usersService: UsersService,\n    private readonly dbWrite: PrismaWriteService,\n    private readonly dbRead: PrismaReadService,\n    private readonly eventTypeService: EventTypesService_2024_06_14,\n    private readonly usersRepository: UsersRepository\n  ) {}\n\n  private async getTeamSlug(teamId: number): Promise<string> {\n    const team = await this.dbRead.prisma.team.findUnique({\n      where: { id: teamId },\n      select: { slug: true },\n    });\n\n    if (!team?.slug) {\n      throw new NotFoundException(`Team with id ${teamId} not found`);\n    }\n    return team.slug;\n  }\n\n  async getUserEventType(user: UserWithProfile, eventTypeId: number) {\n    const organizationId = this.usersService.getUserMainOrgId(user);\n\n    const isUserOrganizationAdmin = organizationId\n      ? await this.membershipsRepository.isUserOrganizationAdmin(user.id, organizationId)\n      : false;\n\n    const eventType = await getEventTypeById({\n      currentOrganizationId: this.usersService.getUserMainOrgId(user),\n      eventTypeId,\n      userId: user.id,\n      userLocale: user.locale ?? \"en\",\n      prisma: this.dbRead.prisma as unknown as PrismaClient,\n      isUserOrganizationAdmin,","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/atoms/services/event-types-atom.service.ts#L65-L101","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","solutions":["Verify the teamId exists in the team table and has a non-null slug before calling the endpoint.","If the team exists but has no slug, set one via the team settings UI or database update.","Clear stale team references from client-side caches or configuration."],"exampleFix":"// before: passing unverified teamId\nconst event = await atomsApi.getPublicEventType({\n  eventSlug: '30min',\n  isTeamEvent: true,\n  teamId: possiblyDeletedTeamId\n});\n\n// after: validate team existence first\nconst team = await api.get(`/v2/teams/${teamId}`);\nif (!team?.slug) {\n  throw new Error(`Team ${teamId} has no slug; configure it in team settings.`);\n}\nconst event = await atomsApi.getPublicEventType({\n  eventSlug: '30min',\n  isTeamEvent: true,\n  teamId: team.id\n});","handlingStrategy":"validation","validationCode":"// Verify team exists and has a slug before using it\nconst verifyTeamSlug = async (api: ApiClient, teamId: number): Promise<string> => {\n  const team = await api.get(`/v2/teams/${teamId}`);\n  if (!team?.slug) {\n    throw new Error(`Team ${teamId} has no slug; set one in team settings before using it for event lookups.`);\n  }\n  return team.slug;\n};","typeGuard":"interface TeamWithSlug { id: number; slug: string; }\nconst hasSlug = (team: { slug?: string | null } | null): team is TeamWithSlug =>\n  team !== null && typeof team.slug === 'string' && team.slug.length > 0;","tryCatchPattern":"// Gracefully handle missing team/slug\ntry {\n  const event = await atomsApi.getPublicEventType({\n    eventSlug,\n    isTeamEvent: true,\n    teamId\n  });\n} catch (err: any) {\n  if (err?.response?.status === 404 && err?.response?.data?.message?.includes('Team with id')) {\n    console.error(`Team ${teamId} not found or has no slug. Verify the team exists.`);\n    // Fall back to user event or prompt user to select a valid team\n  }\n  throw err;\n}","preventionTips":["Validate teamId references an existing team with a slug before passing it to event-type endpoints.","When creating teams programmatically, always assign a slug as part of the creation flow.","Cache team metadata client-side and invalidate it when teams are reorganized."],"tags":["not-found","team","event-types","nestjs","api-v2","atoms"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}