calcom/cal.diy · error · BadRequestException
Invalid start date
Error message
Invalid start date
What it means
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.
Source
Thrown at apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots-input.service.ts:134
}
private async getEventTypeUser(input: ByUsernameAndEventTypeSlug_2024_09_04) {
return await this.usersRepository.findByUsername(input.username);
}
private async getEventTypeTeam(input: ByTeamSlugAndEventTypeSlug_2024_09_04) {
return await this.teamsRepository.findTeamBySlug(input.teamSlug);
}
private adjustStartTime(startTime: string) {
let dateTime = DateTime.fromISO(startTime, { zone: "utc" });
if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0) {
dateTime = dateTime.set({ hour: 0, minute: 0, second: 0, millisecond: 0 });
}
const ISOStartTime = dateTime.toISO();
if (ISOStartTime === null) {
throw new BadRequestException("Invalid start date");
}
return ISOStartTime;
}
private adjustEndTime(endTime: string) {
let dateTime = DateTime.fromISO(endTime, { zone: "utc" });
if (dateTime.hour === 0 && dateTime.minute === 0 && dateTime.second === 0) {
dateTime = dateTime.set({ hour: 23, minute: 59, second: 59 });
}
const ISOEndTime = dateTime.toISO();
if (ISOEndTime === null) {
throw new BadRequestException("Invalid end date");
}
return ISOEndTime;
}View on GitHub (pinned to 176037d0af)
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.
Example fix
// before
fetch(`/v2/slots?start=${dateOnly}`) // '2024-09-04' — too short
// after
const start = DateTime.fromISO(dateOnly, { zone: 'utc' }).startOf('day').toISO();
if (!start) throw new Error('bad start');
fetch(`/v2/slots?start=${encodeURIComponent(start!)}`); Defensive patterns
Strategy: validation
Validate before calling
import { DateTime } from 'luxon';
function toValidStartISO(start: unknown): string {
if (typeof start !== 'string') throw new TypeError('start must be an ISO string');
const dt = DateTime.fromISO(start, { zone: 'utc' });
if (!dt.isValid) throw new RangeError(`Invalid start: ${dt.invalidReason} (${start})`);
return dt.toISO()!;
}
const start = toValidStartISO(input.start); Type guard
function isISODateString(v: unknown): v is string {
if (typeof v !== 'string') return false;
return DateTime.fromISO(v, { zone: 'utc' }).isValid;
} Try / catch
try {
await cal.slots.list({ ..., start });
} catch (e) {
if (e instanceof HttpError && e.statusCode === 400 && /start/i.test(e.message)) {
throw new UserFacingError('Please pick a valid start date/time.');
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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().
Related errors
- Invalid end date
- Invalid start date
- Invalid end date
- Could not adjust timezone for slot ${slot.time} with timezon
- Could not adjust timezone for slot end time ${slot.time} wit
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/302cb12571459aa0.
Report an issue: GitHub.