{"record":{"id":"b421c17e09ae4c23","repo":"calcom/cal.diy","slug":"eventtypeownershipguard-no-user-associated-with","errorCode":null,"errorMessage":"EventTypeOwnershipGuard - No user associated with the request.","messagePattern":"EventTypeOwnershipGuard - No user associated with the request\\.","errorType":"exception","errorClass":"ForbiddenException","httpStatus":403,"severity":"critical","filePath":"apps/api/v2/src/modules/event-types/guards/event-type-ownership.guard.ts","lineNumber":23,"sourceCode":"  CanActivate,\n  ExecutionContext,\n  ForbiddenException,\n  Injectable,\n  NotFoundException,\n} from \"@nestjs/common\";\nimport { Request } from \"express\";\n\n@Injectable()\nexport class EventTypeOwnershipGuard implements CanActivate {\n  constructor(private readonly eventTypesService: EventTypesService_2024_06_14) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest<Request>();\n    const user = request.user as ApiAuthGuardUser | undefined;\n    const eventTypeIdParam = request.params?.eventTypeId;\n\n    if (!user) {\n      throw new ForbiddenException(\"EventTypeOwnershipGuard - No user associated with the request.\");\n    }\n\n    if (!eventTypeIdParam) {\n      throw new BadRequestException(\"Missing eventTypeId param.\");\n    }\n\n    const eventTypeId = Number(eventTypeIdParam);\n    if (!Number.isInteger(eventTypeId) || eventTypeId <= 0) {\n      throw new BadRequestException(\"Invalid eventTypeId param.\");\n    }\n    const eventType = await this.eventTypesService.getUserEventType(user.id, eventTypeId);\n    if (!eventType) {\n      // Mirrors EventTypesService behavior: NotFound when not owned or not present\n      throw new NotFoundException(`Event type with id ${eventTypeId} not found`);\n    }\n\n    return true;\n  }","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/event-types/guards/event-type-ownership.guard.ts#L5-L41","documentation":"Thrown by EventTypeOwnershipGuard.canActivate when request.user is undefined. The guard reads `const user = request.user as ApiAuthGuardUser | undefined` and immediately checks `if (!user)`. A missing user means the guard ran without prior authentication being established on the request object, so it raises ForbiddenException (HTTP 403) rather than 401.","triggerScenarios":"An event-type route decorated with @UseGuards(EventTypeOwnershipGuard) is hit without the ApiAuthGuard (or equivalent auth middleware) having populated request.user — e.g. guard ordering wrong, route accidentally public, or a test request with no auth setup.","commonSituations":"Guard listed before the auth guard in the @UseGuards array; a new route added without the auth guard; integration tests call the controller without mocking request.user; a middleware bug clears request.user.","solutions":["Ensure ApiAuthGuard runs before EventTypeOwnershipGuard on the route/controller (order matters in @UseGuards).","Confirm the route requires authentication (not marked @Public or skipped) so the auth middleware attaches request.user.","In tests, set request.user to a valid ApiAuthGuardUser before invoking the guard."],"exampleFix":"// before\n@UseGuards(EventTypeOwnershipGuard, ApiAuthGuard)\n\n// after\n@UseGuards(ApiAuthGuard, EventTypeOwnershipGuard)","handlingStrategy":"validation","validationCode":"if (!request.user) {\n  throw new UnauthorizedException('Authentication required.');\n}\n// then proceed to EventTypeOwnershipGuard","typeGuard":"const hasApiUser = (req: Request): req is Request & { user: ApiAuthGuardUser } =>\n  !!req.user && typeof (req.user as any).id !== 'undefined';","tryCatchPattern":null,"preventionTips":["Always apply ApiAuthGuard before EventTypeOwnershipGuard in @UseGuards.","Write integration tests that set request.user so the guard is exercised correctly.","Mark routes explicitly as requiring auth to avoid accidental public exposure."],"tags":["event-types","guard","auth","forbidden","nestjs","request-user"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}