calcom/cal.diy · warning · BadRequestException
'to' must not be before 'from'
Error message
'to' must not be before 'from'
What it means
A class-validator custom constraint (IsAfterFrom) on FreebusyUnifiedInput throws a BadRequestException when the `to` field, parsed as a Date, is earlier than the `from` field. The validator deliberately throws rather than returning false, so the message reads exactly as written. The fields are validated as ISO8601 strings by @IsISO8601 first.
Source
Thrown at apps/api/v2/src/modules/cal-unified-calendars/inputs/freebusy-unified.input.ts:19
import { BadRequestException } from "@nestjs/common";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import {
IsISO8601,
IsOptional,
IsTimeZone,
Validate,
ValidationArguments,
ValidatorConstraint,
ValidatorConstraintInterface,
} from "class-validator";
@ValidatorConstraint({ name: "isAfterFrom", async: false })
class IsAfterFrom implements ValidatorConstraintInterface {
validate(to: string, args: ValidationArguments) {
const obj = args.object as { from?: string };
if (!obj.from || !to) return true;
if (new Date(to).getTime() < new Date(obj.from).getTime()) {
throw new BadRequestException("'to' must not be before 'from'");
}
return true;
}
defaultMessage() {
return "'to' must not be before 'from'";
}
}
export class FreebusyUnifiedInput {
@IsISO8601()
@ApiProperty({
type: String,
description: "Start of the date range (ISO 8601 date or date-time)",
example: "2026-03-10",
})
from!: string;
@IsISO8601()View on GitHub (pinned to 176037d0af)
Solutions
- Ensure the client sends `from` <= `to` (preferably from < to).
- Validate the range client-side before the request: `if (new Date(to) < new Date(from)) throw ...`.
- When converting local times to ISO, convert both ends through the same timezone so they stay ordered.
Example fix
// before
const body = { from: '2026-03-10T23:00:00Z', to: '2026-03-10T01:00:00Z' };
// after
const body = { from: '2026-03-10T01:00:00Z', to: '2026-03-10T23:00:00Z' }; Defensive patterns
Strategy: validation
Validate before calling
function isValidRange(from: string, to: string): boolean {
const f = new Date(from).getTime();
const t = new Date(to).getTime();
return !Number.isNaN(f) && !Number.isNaN(t) && t >= f;
}
if (!isValidRange(body.from, body.to)) throw new Error("'to' must not be before 'from'"); Type guard
function isISO8601Pair(v: unknown): v is { from: string; to: string } {
if (typeof v !== 'object' || v === null) return false;
const o = v as any;
return typeof o.from === 'string' && typeof o.to === 'string'
&& !Number.isNaN(new Date(o.from).getTime())
&& !Number.isNaN(new Date(o.to).getTime());
} Prevention
- Validate from <= to client-side before submitting.
- Convert both endpoints through the same timezone when building the ISO strings.
- Use date-time strings (not date-only) when crossing timezones to avoid off-by-one days.
When it happens
Trigger: POST /v2/.../free-busy (or any endpoint accepting FreebusyUnifiedInput) with body { from: '2026-03-10', to: '2026-03-09' }, or any payload where new Date(to).getTime() < new Date(from).getTime(). Also triggered by timezone-shifted date-times that make `to` fall before `from` in UTC.
Common situations: Client swaps from/to; timezone conversion bug makes a 23:00 `to` slip to the previous UTC day; copy-paste of the same date-time on both sides with millisecond differences.
Related errors
- ApiKeysService -Cannot set both apiKeyDaysValid and apiKeyNe
- teamId is required for team events, please provide a valid t
- username is required for non-team events, please provide a v
- Invalid connectionId
- Invalid email ${trimmed}
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/276e08eb3e421127.
Report an issue: GitHub.