{"record":{"id":"302cb12571459aa0","repo":"calcom/cal.diy","slug":"invalid-start-date","errorCode":null,"errorMessage":"Invalid start date","messagePattern":"Invalid start date","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-input.service.ts","lineNumber":134,"sourceCode":"  }\n\n  private async getEventTypeUser(input: ByUsernameAndEventTypeSlug_2024_09_04) {\n    return await this.usersRepository.findByUsername(input.username);\n  }\n\n  private async getEventTypeTeam(input: ByTeamSlugAndEventTypeSlug_2024_09_04) {\n    return await this.teamsRepository.findTeamBySlug(input.teamSlug);\n  }\n\n  private adjustStartTime(startTime: string) {\n    let dateTime = DateTime.fromISO(startTime, { zone: \"utc\" });\n    if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0) {\n      dateTime = dateTime.set({ hour: 0, minute: 0, second: 0, millisecond: 0 });\n    }\n\n    const ISOStartTime = dateTime.toISO();\n    if (ISOStartTime === null) {\n      throw new BadRequestException(\"Invalid start date\");\n    }\n\n    return ISOStartTime;\n  }\n\n  private adjustEndTime(endTime: string) {\n    let dateTime = DateTime.fromISO(endTime, { zone: \"utc\" });\n    if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0) {\n      dateTime = dateTime.set({ hour: 23, minute: 59, second: 59 });\n    }\n\n    const ISOEndTime = dateTime.toISO();\n    if (ISOEndTime === null) {\n      throw new BadRequestException(\"Invalid end date\");\n    }\n\n    return ISOEndTime;\n  }","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-input.service.ts#L116-L152","documentation":"A NestJS BadRequestException (HTTP 400) from SlotsInputService_2024_09_04.adjustStartTime. Luxon's DateTime.fromISO(startTime, {zone:'utc'}).toISO() returned null — the `start` query parameter could not be parsed into a valid ISO datetime. This guards the slot query window start.","triggerScenarios":"Calling GET /v2/slots/2024-09-04 with a `start` value that is empty, malformed (e.g. '2024-09-04', 'tomorrow', a unix timestamp as a number), in an unsupported locale format, or contains invalid characters after URL decoding.","commonSituations":"Passing a bare date 'YYYY-MM-DD' that luxon parses but then toISO returns a value — actually here the issue is fully unparseable strings; passing a JS Date.toString() output with timezone label; client building the string with a broken template literal; forgetting to convert a native Date via toISOString().","solutions":["Send `start` as a full ISO 8601 UTC string, e.g. new Date().toISOString() (YYYY-MM-DDTHH:mm:ss.sssZ).","Validate the string with luxon client-side: DateTime.fromISO(start, {zone:'utc'}).isValid must be true before the request.","URL-encode the value so '+' and ':' survive transport.","Ensure the field is not empty or undefined — the pipe may pass it through but luxon rejects it here."],"exampleFix":"// before\nfetch(`/v2/slots?start=${dateOnly}`)  // '2024-09-04' — too short\n\n// after\nconst start = DateTime.fromISO(dateOnly, { zone: 'utc' }).startOf('day').toISO();\nif (!start) throw new Error('bad start');\nfetch(`/v2/slots?start=${encodeURIComponent(start!)}`);","handlingStrategy":"validation","validationCode":"import { DateTime } from 'luxon';\n\nfunction toValidStartISO(start: unknown): string {\n  if (typeof start !== 'string') throw new TypeError('start must be an ISO string');\n  const dt = DateTime.fromISO(start, { zone: 'utc' });\n  if (!dt.isValid) throw new RangeError(`Invalid start: ${dt.invalidReason} (${start})`);\n  return dt.toISO()!;\n}\nconst start = toValidStartISO(input.start);","typeGuard":"function isISODateString(v: unknown): v is string {\n  if (typeof v !== 'string') return false;\n  return DateTime.fromISO(v, { zone: 'utc' }).isValid;\n}","tryCatchPattern":"try {\n  await cal.slots.list({ ..., start });\n} catch (e) {\n  if (e instanceof HttpError && e.statusCode === 400 && /start/i.test(e.message)) {\n    throw new UserFacingError('Please pick a valid start date/time.');\n  }\n  throw e;\n}","preventionTips":["Always build start via new Date().toISOString() or luxon toISO().","Run DateTime.fromISO(start, {zone:'utc'}).isValid before sending.","URL-encode the value to preserve ':' and '+'.","Never send a bare date (YYYY-MM-DD) without a time component."],"tags":["calcom-api","slots","bad-request","luxon","datetime","validation"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}