{"record":{"id":"8faf844b2e3d90e8","repo":"calcom/cal.diy","slug":"username-or-password-cannot-be-empty","errorCode":null,"errorMessage":"Username or password cannot be empty","messagePattern":"Username or password cannot be empty","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts","lineNumber":64,"sourceCode":"    const { connectedCalendars } = await this.calendarsService.getCalendars(userId);\n    const appleCalendar = connectedCalendars.find(\n      (cal: { integration: { type: string } }) => cal.integration.type === APPLE_CALENDAR_TYPE\n    );\n    if (!appleCalendar) {\n      throw new UnauthorizedException(\"Apple calendar not connected.\");\n    }\n    if (appleCalendar.error?.message) {\n      throw new UnauthorizedException(appleCalendar.error?.message);\n    }\n\n    return {\n      status: SUCCESS_STATUS,\n    };\n  }\n\n  async saveCalendarCredentials(userId: number, userEmail: string, username: string, password: string) {\n    if (!username || !password || username.length <= 1 || password.length <= 1) {\n      throw new BadRequestException(`Username or password cannot be empty`);\n    }\n\n    const existingAppleCalendarCredentials = await this.credentialRepository.getAllUserCredentialsByTypeAndId(\n      APPLE_CALENDAR_TYPE,\n      userId\n    );\n\n    let hasMatchingUsernameAndPassword = false;\n\n    if (existingAppleCalendarCredentials.length > 0) {\n      const hasCalendarWithGivenCredentials = existingAppleCalendarCredentials.find(\n        (calendarCredential: Credential) => {\n          const decryptedKey = JSON.parse(\n            symmetricDecrypt(calendarCredential.key as string, process.env.CALENDSO_ENCRYPTION_KEY || \"\")\n          );\n\n          if (decryptedKey.username === username) {\n            if (decryptedKey.password === password) {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts#L46-L82","documentation":"Thrown by AppleCalendarService.saveCalendarCredentials (apple-calendar.service.ts:64) as BadRequestException (HTTP 400) when username or password is falsy or has length <= 1. Pure input validation; fully preventable on the client before the request is sent.","triggerScenarios":"POST /v2/calendars/apple_calendar/save with empty/undefined username or password; whitespace-only fields; malformed request body missing keys; integration test omitting fields.","commonSituations":"Frontend bug not trimming/validating input; API client forgetting to populate both fields; form submitted before the user typed a value.","solutions":["Validate on the client that both username and password are non-empty strings of length >= 2 before calling save.","Add a Zod/schema check on the request DTO mirroring the service's guard.","Return a form-level validation error instead of hitting the API."],"exampleFix":"// before: no client validation\nawait api.post('/v2/calendars/apple_calendar/save', { username, password }); // 400 if empty\n\n// after: validate before sending\nconst Schema = z.object({\n  username: z.string().trim().min(2),\n  password: z.string().min(2),\n});\nconst body = Schema.parse({ username, password });\nawait api.post('/v2/calendars/apple_calendar/save', body);","handlingStrategy":"validation","validationCode":"// Validate client-side before calling save\nimport { z } from 'zod';\nconst SaveAppleSchema = z.object({\n  username: z.string().trim().min(2, 'username too short'),\n  password: z.string().min(2, 'password too short'),\n});\nconst body = SaveAppleSchema.parse({ username, password });\nawait api.post('/v2/calendars/apple_calendar/save', body);","typeGuard":"function isValidAppleInput(username, password) {\n  return typeof username === 'string' && typeof password === 'string'\n    && username.trim().length > 1 && password.length > 1;\n}","tryCatchPattern":null,"preventionTips":["Mirror the service's min-length-2 rule in the client DTO schema.","Trim username before validation; keep password as-is.","Disable the submit button until both fields pass client validation."],"tags":["apple-calendar","validation","input","http-400"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}