calcom/cal.diy · error · BadRequestException
Invalid Date.
Error message
Invalid Date.
What it means
Thrown inside the catch block of isDateString() in the OOO (out-of-office) DTO transformer. isDateString() runs a strict ISO-8601 UTC regex against the input; the try/catch is a defensive guard around RegExp.prototype.test(). In practice RegExp.test() coerces its argument to a string and does not throw for normal values, so this branch is effectively unreachable for well-typed string inputs and only fires if a non-stringable value (e.g. a Symbol or a getter that throws) reaches the regex at runtime despite the TypeScript signature.
Source
Thrown at apps/api/v2/src/modules/ooo/inputs/ooo.input.ts:23
import { SkipTakePagination } from "@calcom/platform-types";
export enum OutOfOfficeReason {
UNSPECIFIED = "unspecified",
VACATION = "vacation",
TRAVEL = "travel",
SICK_LEAVE = "sick",
PUBLIC_HOLIDAY = "public_holiday",
}
export type OutOfOfficeReasonType = `${OutOfOfficeReason}`;
const isDateString = (dateString: string) => {
try {
const isoDateRegex = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{3})?Z$/;
return isoDateRegex.test(dateString);
} catch {
throw new BadRequestException("Invalid Date.");
}
};
export class CreateOutOfOfficeEntryDto {
@Transform(({ value }: { value: string }) => {
if (isDateString(value)) {
const date = new Date(value);
date.setUTCHours(0, 0, 0, 0);
return date;
}
throw new BadRequestException("Invalid Date.");
})
@IsDate()
@ApiProperty({
description: "The start date and time of the out of office period in ISO 8601 format in UTC timezone.",
example: "2023-05-01T00:00:00.000Z",
})
start!: Date;View on GitHub (pinned to 176037d0af)
Solutions
- Confirm the request body sends start/end as ISO-8601 strings (e.g. "2023-05-01T00:00:00.000Z"), never as Date objects or other primitives.
- If you maintain this code, make isDateString() return false instead of throwing on a failed test — the catch is dead for strings and the line-34 path already handles the negative case.
- Add a class-validator @IsString() / @Matches() guard before @Transform so non-string values are rejected earlier with a clearer message.
Example fix
// before
const isDateString = (dateString: string) => {
try {
const isoDateRegex = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{3})?Z$/;
return isoDateRegex.test(dateString);
} catch {
throw new BadRequestException("Invalid Date.");
}
};
// after (remove the unreachable catch; let the caller throw)
const ISO_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d{3})?Z$/;
const isDateString = (dateString: string): boolean => ISO_DATE_REGEX.test(dateString); Defensive patterns
Strategy: validation
Validate before calling
const ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
const ensureIsoString = (v: unknown): string => {
if (typeof v !== 'string' || !ISO.test(v))
throw new Error('start/end must be ISO-8601 UTC string');
return v;
}; Type guard
const isIsoDateString = (v: unknown): v is string =>
typeof v === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(v); Prevention
- Always serialize dates with Date.prototype.toISOString() before sending.
- Never pass Date objects, BigInt, or Symbols into the start/end JSON fields.
- Add a class-validator @Matches(/...Z$/) decorator upstream of @Transform.
When it happens
Trigger: A POST/PATCH to /v2/ooo (create/update out-of-office entry) where the request body reaches the @Transform pipe with a value whose toString/getter throws during regex.test(). Cannot be triggered by an ordinary malformed date string — those fall through to the line-34 throw instead.
Common situations: A client serializing a Date object, BigInt, or Symbol into the start/end JSON field; a class-transformer / class-validator pipeline misconfigured to pass non-primitives; a custom serialization layer that injects objects with throwing toJSON() hooks.
Related errors
- Start date must be before end date.
- Invalid email ${trimmed}
- No user id found in request params.
- No ooo entry id found in request params.
- Please specify both ooo start and end time.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/e76d285c4668baf8.
Report an issue: GitHub.