{"record":{"id":"d88236bfc1c21902","repo":"calcom/cal.diy","slug":"could-not-create-utc-time-for-slot-slot-time","errorCode":null,"errorMessage":"Could not create UTC time for slot ${slot.time}","messagePattern":"Could not create UTC time for slot (.+?)","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-output.service.ts","lineNumber":156,"sourceCode":"              );\n            }\n\n            if (!eventType?.seatsPerTimeSlot) {\n              return this.getAvailableRangeSlot(start, end);\n            }\n            return this.getAvailableRangeSlotSeated(\n              start,\n              end,\n              slot.attendees || 0,\n              eventType.seatsPerTimeSlot ?? undefined,\n              slot.bookingUid\n            );\n          } else {\n            const start = DateTime.fromISO(slot.time, { zone: \"utc\" }).toISO();\n            const end = DateTime.fromISO(slot.time, { zone: \"utc\" }).plus({ minutes: slotDuration }).toISO();\n\n            if (!start || !end) {\n              throw new BadRequestException(`Could not create UTC time for slot ${slot.time}`);\n            }\n\n            if (!eventType?.seatsPerTimeSlot) {\n              return this.getAvailableRangeSlot(start, end);\n            }\n            return this.getAvailableRangeSlotSeated(\n              start,\n              end,\n              slot.attendees || 0,\n              eventType.seatsPerTimeSlot ?? undefined,\n              slot.bookingUid\n            );\n          }\n        });\n      }\n      return acc;\n    }, {});\n","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-output.service.ts#L138-L174","documentation":"A NestJS BadRequestException (HTTP 400) from SlotsOutputService_2024_09_04.getAvailableRangeSlots — the no-timeZone branch. The slot.time itself could not be converted to ISO even in UTC: DateTime.fromISO(slot.time,{zone:'utc'}).toISO() returned null. This is a data-integrity signal: the upstream availableSlots service produced a slot whose time is not a valid ISO string.","triggerScenarios":"GET /v2/slots with format=range and no timeZone, where the availability engine returned a malformed slot.time (e.g. an empty string, a date-only value, or a corrupt entry). The client request is fine; the server's slot data is bad.","commonSituations":"A bug or override in AvailableSlotsService producing non-ISO times; a database row with a null/empty startTime surfacing as an empty string; a custom event type whose schedule produces an edge-case slot luxon cannot render.","solutions":["Retry the request once — transient bad slots can clear on availability recompute.","Narrow the query window (start/end) to isolate which date produces the bad slot and report it.","Switch format to 'time' (default) instead of 'range' to bypass the range-specific UTC conversion path.","File a server-side bug: AvailableSlotsService should never emit a slot whose time fails DateTime.fromISO."],"exampleFix":"// before\nfetch(`/v2/slots?format=range&...`)\n\n// after — fall back to default time format, or shrink the window\nfetch(`/v2/slots?format=time&...`)\n// then report the bad date range to the platform team","handlingStrategy":"retry","validationCode":"// This error reflects bad SERVER-side slot data, not caller input.\n// Mitigation: shrink the window so the request avoids the corrupt slot.\nfunction safeWindow(startISO: string, endISO: string) {\n  const start = DateTime.fromISO(startISO, { zone: 'utc' });\n  const end = DateTime.fromISO(endISO, { zone: 'utc' });\n  if (!start.isValid || !end.isValid) throw new RangeError('bad window');\n  // keep windows short to reduce chance of hitting a corrupt slot\n  const span = end.diff(start, 'days').days;\n  if (span > 7) throw new RangeError('narrow the window to <= 7 days for range format');\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await cal.slots.list({ format: 'range', ... });\n} catch (e) {\n  if (e instanceof HttpError && e.statusCode === 400 && /Could not create UTC time/i.test(e.message)) {\n    // retry once with default time format, then report\n    return cal.slots.list({ format: 'time', ... });\n  }\n  throw e;\n}","preventionTips":["Prefer the default 'time' format over 'range' unless you need explicit end times.","Keep query windows narrow to reduce exposure to bad slot rows.","Retry once with a different format before surfacing failure.","Report persistent corrupt-slot errors to the platform team with the date range."],"tags":["calcom-api","slots","bad-request","luxon","data-integrity","range-format"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}