{"record":{"id":"d110b73fce9d3b9b","repo":"calcom/cal.diy","slug":"invalid-eventtypeid-param","errorCode":null,"errorMessage":"Invalid eventTypeId param.","messagePattern":"Invalid 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":32,"sourceCode":"export 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":14,"sourceCodeEnd":43,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/event-types/guards/event-type-ownership.guard.ts#L14-L43","documentation":"Thrown by EventTypeOwnershipGuard.canActivate when the eventTypeId param cannot be coerced to a positive integer. After confirming the param exists, the guard computes Number(eventTypeIdParam) and rejects it via BadRequestException (HTTP 400) if Number.isInteger is false or the value is <= 0. This catches strings like 'abc', '1.5', '-3', '' after coercion.","triggerScenarios":"Client sends eventTypeId as a non-numeric string, a float, a negative number, or an empty string in the URL. Examples: /event-types/abc, /event-types/-5, /event-types/12.0, /event-types/.","commonSituations":"Frontend builds the URL from an untrimmed/free-text input; a UUID or slug accidentally sent where an integer id is expected; trailing slash producing empty param; copy-paste corruption of the id.","solutions":["Validate the eventTypeId client-side (positive integer regex) before issuing the request.","Use the numeric database id from the prior list response rather than any user-supplied text.","If accepting slugs is desired, change the guard/service contract explicitly rather than relying on this integer check."],"exampleFix":"// before\nfetch(`/event-types/${userInput}`)\n\n// after\nconst id = Number(userInput);\nif (!Number.isInteger(id) || id <= 0) throw new Error('Invalid id');\nfetch(`/event-types/${id}`)","handlingStrategy":"validation","validationCode":"const id = Number(request.params.eventTypeId);\nif (!Number.isInteger(id) || id <= 0) {\n  throw new BadRequestException('Invalid eventTypeId param.');\n}","typeGuard":"const isPositiveInt = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isInteger(v) && v > 0;","tryCatchPattern":null,"preventionTips":["Validate ids on the client before building the URL.","Use numeric ids from list responses, not user-typed strings.","Add a ParseIntPipe if migrating to Nest pipes for cleaner validation."],"tags":["event-types","guard","validation","params","bad-request","integer"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}