calcom/cal.diy · error · BadRequestException

Invalid time range given - check the 'startTime' and 'endTim

Error message

Invalid time range given - check the 'startTime' and 'endTime' query parameters.

What it means

BadRequestException (HTTP 400) thrown by the slots controller when the underlying getAvailableSlots call throws an Error whose message contains the substring 'Invalid time range given'. The controller inspects the upstream error text and rewraps it as a 400 pointing the caller at the startTime/endTime query params. The original throw lives in the slots/getSlots domain logic and signals that the requested window is empty, inverted, or otherwise malformed.

Source

Thrown at apps/api/v2/src/modules/slots/slots-2024-04-15/controllers/slots.controller.ts:217

      const { slots } = await this.slotsOutputService.getOutputSlots(
        availableSlots,
        query.duration,
        query.eventTypeId,
        query.slotFormat,
        query.timeZone
      );

      return {
        data: {
          slots,
        },
        status: SUCCESS_STATUS,
      };
    } catch (error) {
      if (error instanceof Error) {
        if (error.message.includes("Invalid time range given")) {
          throw new BadRequestException(
            "Invalid time range given - check the 'startTime' and 'endTime' query parameters."
          );
        }

        if (TRPC_ERROR_MAP[error.message as keyof typeof TRPC_ERROR_CODE]) {
          throw new TRPCError({ code: error.message as TRPCErrorCode });
        }
      }

      throw error;
    }
  }
}

View on GitHub (pinned to 176037d0af)

Solutions

  1. Ensure startTime is strictly before endTime and the window has positive duration when sent.
  2. Send full ISO-8601 instants (with Z) for both params, not bare dates.
  3. Validate client-side that endTime is in the future and after startTime before firing the request.

Example fix

// before
api.get('/slots/2024-04-15', { startTime: end, endTime: start }); // swapped
// after
const start = new Date();
const end = new Date(start.getTime() + 7 * 86400000);
api.get('/slots/2024-04-15', { startTime: start.toISOString(), endTime: end.toISOString() });
Defensive patterns

Strategy: validation

Validate before calling

function buildSlotsQuery(startTime: Date, endTime: Date) {
  if (!(startTime.getTime() < endTime.getTime()))
    throw new Error('startTime must be strictly before endTime');
  if (endTime.getTime() <= Date.now())
    throw new Error('endTime must be in the future');
  return { startTime: startTime.toISOString(), endTime: endTime.toISOString() };
}

Type guard

const isValidSlotRange = (start: Date, end: Date): boolean =>
  start.getTime() < end.getTime() && end.getTime() > Date.now();

Prevention

When it happens

Trigger: GET /v2/slots/2024-04-15 with startTime >= endTime, startTime/endTime outside allowed bounds, endTime in the past, or a window the engine considers degenerate (zero or negative duration after timezone normalization).

Common situations: Client computes endTime by subtracting instead of adding; passes startTime/endTime as date-only so the slot service sees them as equal midnight; timezone conversion flips the order; a date picker allowing the user to pick an end before the start.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/4d9060f0dc77e926. Report an issue: GitHub.