{"record":{"id":"b853b4698cef67fb","repo":"calcom/cal.diy","slug":"missing-eventtypeid-param","errorCode":null,"errorMessage":"Missing eventTypeId param.","messagePattern":"Missing eventTypeId param\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"apps/api/v2/src/modules/event-types/guards/event-type-ownership.guard.ts","lineNumber":27,"sourceCode":"  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  }\n}\n","sourceCodeStart":9,"sourceCodeEnd":43,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/event-types/guards/event-type-ownership.guard.ts#L9-L43","documentation":"Thrown by EventTypeOwnershipGuard.canActivate when the eventTypeId route param is absent. After the user check passes, the guard reads request.params?.eventTypeId and raises BadRequestException (HTTP 400) if it is falsy. This indicates the route path/controller mapping does not actually include :eventTypeId.","triggerScenarios":"A route decorated with EventTypeOwnershipGuard whose path lacks the :eventTypeId segment, or the param name was renamed (e.g. :id) so request.params.eventTypeId is undefined. The guard refuses to proceed without a target id.","commonSituations":"Controller @Get/@Put/@Delete path template changed and :eventTypeId dropped or renamed; guard applied to a collection route (e.g. /event-types) instead of an item route (/event-types/:eventTypeId); typo in param name between path and guard.","solutions":["Ensure the route path includes :eventTypeId, e.g. @Delete(':eventTypeId').","If the param name must differ, update the guard to read the actual param name or use a shared constant.","Do not apply this ownership guard to collection routes that have no id param."],"exampleFix":"// before\n@Delete(':id')\n@UseGuards(EventTypeOwnershipGuard)\n\n// after\n@Delete(':eventTypeId')\n@UseGuards(EventTypeOwnershipGuard)","handlingStrategy":"validation","validationCode":"const eventTypeIdParam = request.params?.eventTypeId;\nif (!eventTypeIdParam) {\n  throw new BadRequestException('Missing eventTypeId param.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the :eventTypeId segment in every route path guarded by EventTypeOwnershipGuard.","Share a route-param-name constant between path templates and the guard.","Do not attach the ownership guard to collection routes."],"tags":["event-types","guard","routing","params","bad-request"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}