calcom/cal.diy · warning · BadRequestException

Invalid time format. Expected format(ISO8061): 2025-0412T13:

Error message

Invalid time format. Expected format(ISO8061): 2025-0412T13:17:56.324Z. Received: ${value}

What it means

Thrown by transformStringToDate when the time portion after the 'T' separator cannot be split into exactly three colon-separated parts (hours, minutes, seconds). The code strips milliseconds first, then splits on ':' and requires exactly 3 segments. A time like '09:00' (only 2 parts) or '09' (1 part) will trigger HTTP 400.

Source

Thrown at apps/api/v2/src/platform/schedules/schedules_2024_04_15/inputs/create-availability.input.ts:39

function transformStringToDate(value: string, key: string): Date {
  if (!value) {
    throw new BadRequestException(
      `Missing ${key}. Expected value is in ISO8061 format e.g. 2025-0412T13:17:56.324Z`
    );
  }

  const dateTimeParts = value.split("T");
  if (dateTimeParts.length !== 2) {
    throw new BadRequestException(
      `Invalid datestring format. Expected format(ISO8061): 2025-04-12T13:17:56.324Z. Received: ${value}`
    );
  }

  const timePart = dateTimeParts[1].split(".")[0]; // Removes milliseconds
  const parts = timePart.split(":");

  if (parts.length !== 3) {
    throw new BadRequestException(
      `Invalid time format. Expected format(ISO8061): 2025-0412T13:17:56.324Z. Received: ${value}`
    );
  }
  const [hours, minutes, seconds] = parts.map(Number);

  if (hours < 0 || hours > 23) {
    throw new BadRequestException(`Invalid ${key} hours. Expected value between 0 and 23`);
  }

  if (minutes < 0 || minutes > 59) {
    throw new BadRequestException(`Invalid ${key} minutes. Expected value between 0 and 59`);
  }

  if (seconds < 0 || seconds > 59) {
    throw new BadRequestException(`Invalid ${key} seconds. Expected value between 0 and 59`);
  }

  return new Date(new Date().setUTCHours(hours, minutes, seconds, 0));

View on GitHub (pinned to 176037d0af)

Solutions

  1. Ensure the time portion includes hours, minutes, AND seconds: '2025-04-12T09:00:00.000Z'.
  2. If your client only has hours and minutes, append ':00' for seconds before sending: startTime + ':00'.
  3. Migrate to the 2024-06-11 schedule API which uses simpler 'hh:mm' format without seconds.

Example fix

// before
"startTime": "2025-04-12T09:00.000Z"
// after
"startTime": "2025-04-12T09:00:00.000Z"
Defensive patterns

Strategy: validation

Validate before calling

function validateTimeString(value: string, fieldName: string): void {
  const parts = value.split('T');
  if (parts.length !== 2) throw new Error(`${fieldName}: missing T separator`);
  const timePart = parts[1].split('.')[0]; // strip ms
  const segments = timePart.split(':');
  if (segments.length !== 3) {
    throw new Error(`${fieldName}: time must be hh:mm:ss, got ${timePart}`);
  }
}

validateTimeString(item.startTime, 'startTime');
validateTimeString(item.endTime, 'endTime');

Type guard

function hasThreePartTime(isoString: string): boolean {
  const tIndex = isoString.indexOf('T');
  if (tIndex === -1) return false;
  const timePart = isoString.slice(tIndex + 1).split('.')[0];
  return timePart.split(':').length === 3;
}

Try / catch

try {
  await api.post('/v2/schedules', payload);
} catch (error) {
  if (error.response?.status === 400 && error.response.data.message?.includes('Invalid time format')) {
    // The time portion needs hh:mm:ss — append ':00' if seconds are missing
    console.error('Fix time format to include seconds:', error.response.data.message);
  }
  throw error;
}

Prevention

When it happens

Trigger: Sending a time portion of '09:00' without seconds (only 2 colon-separated parts); sending '0900' with no colons at all; sending '9' as the time portion; sending a time with timezone offset like '09:00:00+02:00' which produces more than 3 parts after splitting.

Common situations: Most time pickers and libraries output 'HH:mm' without seconds; client uses a simplified format not matching the strict 3-part requirement; timezone offset appended to the time portion breaks the split.

Related errors


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