calcom/cal.diy · error · BadRequestException
Could not adjust timezone for slot end time ${slot.time} wit
Error message
Could not adjust timezone for slot end time ${slot.time} with timezone ${timeZone} What it means
A NestJS BadRequestException (HTTP 400) from SlotsOutputService_2024_09_04.getAvailableRangeSlots — the end-time conversion branch. The slot end (slot.time + slotDuration minutes) converted to the target timezone returned null from toISO(). Distinguished from 165 because the start conversion succeeded but the end (after plus({minutes: slotDuration})) failed.
Source
Thrown at apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-output.service.ts:136
>((acc, [date, slots]) => {
const availableTimeSlots = slots.filter((slot) => !slot.away);
if (availableTimeSlots.length > 0) {
acc[date] = availableTimeSlots.map((slot) => {
if (timeZone) {
const start = DateTime.fromISO(slot.time, { zone: "utc" }).setZone(timeZone).toISO();
if (!start) {
throw new BadRequestException(
`Could not adjust timezone for slot ${slot.time} with timezone ${timeZone}`
);
}
const end = DateTime.fromISO(slot.time, { zone: "utc" })
.plus({ minutes: slotDuration })
.setZone(timeZone)
.toISO();
if (!end) {
throw new BadRequestException(
`Could not adjust timezone for slot end time ${slot.time} with timezone ${timeZone}`
);
}
if (!eventType?.seatsPerTimeSlot) {
return this.getAvailableRangeSlot(start, end);
}
return this.getAvailableRangeSlotSeated(
start,
end,
slot.attendees || 0,
eventType.seatsPerTimeSlot ?? undefined,
slot.bookingUid
);
} else {
const start = DateTime.fromISO(slot.time, { zone: "utc" }).toISO();
const end = DateTime.fromISO(slot.time, { zone: "utc" }).plus({ minutes: slotDuration }).toISO();
View on GitHub (pinned to 176037d0af)
Solutions
- Always pass an explicit duration query param for range requests when the event type length may be null.
- Validate slotDuration is a finite positive integer before relying on it.
- Validate timeZone as in 164/165.
- If the event type is non-variable, ensure eventType.length is configured.
Example fix
// before
fetch(`/v2/slots?format=range&eventTypeSlug=...&timeZone=${tz}`) // no duration, ET length null
// after
fetch(`/v2/slots?format=range&eventTypeSlug=...&duration=30&timeZone=${encodeURIComponent(tz)}`); Defensive patterns
Strategy: validation
Validate before calling
import { DateTime } from 'luxon';
function assertRangeParams(duration: unknown, tz: unknown) {
if (duration !== undefined) {
const d = Number(duration);
if (!Number.isFinite(d) || d <= 0) throw new RangeError('duration must be a positive number of minutes');
}
if (tz !== undefined && (typeof tz !== 'string' || !DateTime.now().setZone(tz).isValid)) {
throw new RangeError(`Unsupported timeZone: ${tz}`);
}
}
assertRangeParams(input.duration, input.timeZone); Type guard
function isPositiveFiniteMinutes(v: unknown): v is number {
return typeof v === 'number' && Number.isFinite(v) && v > 0;
} Try / catch
try {
await cal.slots.list({ format: 'range', duration, ..., timeZone });
} catch (e) {
if (e instanceof HttpError && e.statusCode === 400 && /end time|timezone/i.test(e.message)) {
// retry with explicit duration or without timeZone
return cal.slots.list({ format: 'range', duration: eventType.length, ... /* no tz */ });
}
throw e;
} Prevention
- Always pass an explicit duration for range requests on event types whose length may be null.
- Validate the timezone as IANA before sending.
- Reject NaN/Infinity/negative durations client-side.
- Confirm eventType.length is set before relying on the default.
When it happens
Trigger: GET /v2/slots with format=range and a timeZone where the start converts but the computed end crosses into an invalid instant — in practice this fires when slotDuration is undefined/NaN producing an invalid DateTime, or when slot.time itself is borderline and the addition overflows luxon's representable range.
Common situations: Event type has no length and no duration passed (slotDuration = undefined → plus undefined minutes → invalid); duration query param coerced to NaN; extreme durations; DST gap near the slot combined with an unusual zone.
Related errors
- Could not adjust timezone for slot ${slot.time} with timezon
- Could not create UTC time for slot ${slot.time}
- Invalid end date
- Invalid start date
- Invalid end date
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/a5055721995d4828.
Report an issue: GitHub.