calcom/cal.diy · critical · ForbiddenException

EventTypeOwnershipGuard - No user associated with the reques

Error message

EventTypeOwnershipGuard - No user associated with the request.

What it means

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.

Source

Thrown at apps/api/v2/src/modules/event-types/guards/event-type-ownership.guard.ts:23

  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
  NotFoundException,
} from "@nestjs/common";
import { Request } from "express";

@Injectable()
export class EventTypeOwnershipGuard implements CanActivate {
  constructor(private readonly eventTypesService: EventTypesService_2024_06_14) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest<Request>();
    const user = request.user as ApiAuthGuardUser | undefined;
    const eventTypeIdParam = request.params?.eventTypeId;

    if (!user) {
      throw new ForbiddenException("EventTypeOwnershipGuard - No user associated with the request.");
    }

    if (!eventTypeIdParam) {
      throw new BadRequestException("Missing eventTypeId param.");
    }

    const eventTypeId = Number(eventTypeIdParam);
    if (!Number.isInteger(eventTypeId) || eventTypeId <= 0) {
      throw new BadRequestException("Invalid eventTypeId param.");
    }
    const eventType = await this.eventTypesService.getUserEventType(user.id, eventTypeId);
    if (!eventType) {
      // Mirrors EventTypesService behavior: NotFound when not owned or not present
      throw new NotFoundException(`Event type with id ${eventTypeId} not found`);
    }

    return true;
  }

View on GitHub (pinned to 176037d0af)

Solutions

  1. Ensure ApiAuthGuard runs before EventTypeOwnershipGuard on the route/controller (order matters in @UseGuards).
  2. Confirm the route requires authentication (not marked @Public or skipped) so the auth middleware attaches request.user.
  3. In tests, set request.user to a valid ApiAuthGuardUser before invoking the guard.

Example fix

// before
@UseGuards(EventTypeOwnershipGuard, ApiAuthGuard)

// after
@UseGuards(ApiAuthGuard, EventTypeOwnershipGuard)
Defensive patterns

Strategy: validation

Validate before calling

if (!request.user) {
  throw new UnauthorizedException('Authentication required.');
}
// then proceed to EventTypeOwnershipGuard

Type guard

const hasApiUser = (req: Request): req is Request & { user: ApiAuthGuardUser } =>
  !!req.user && typeof (req.user as any).id !== 'undefined';

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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