calcom/cal.diy · warning · BadRequestException

Missing ${key}. Expected value is in ISO8061 format e.g. 202

Error message

Missing ${key}. Expected value is in ISO8061 format e.g. 2025-0412T13:17:56.324Z

What it means

Thrown by the class-transformer @Transform pipe on CreateAvailabilityInput_2024_04_15 when the startTime or endTime field is absent or falsy. The transformStringToDate helper runs before class-validator's @IsDate check, so a missing field never reaches validation — it fails immediately with HTTP 400. The error message embeds the property name (startTime or endTime) via the ${key} interpolation.

Source

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

export class CreateAvailabilityInput_2024_04_15 {
  @IsArray()
  @IsNumber({}, { each: true })
  @ApiProperty({ example: [1, 2] })
  days!: number[];

  @IsDate()
  @Transform(({ value, key }: TransformFnParams) => transformStringToDate(value, key))
  startTime!: Date;

  @IsDate()
  @Transform(({ value, key }: TransformFnParams) => transformStringToDate(value, key))
  endTime!: Date;
}

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}`
    );

View on GitHub (pinned to 176037d0af)

Solutions

  1. Ensure every availability object in the request body includes both startTime and endTime as ISO 8601 strings (e.g. "2025-04-12T13:17:56.324Z").
  2. Validate the request body shape before sending it — confirm startTime and endTime are non-empty strings.
  3. Upgrade to the 2024-06-11 schedule API version which accepts simpler 'hh:mm' time strings instead of full ISO timestamps.

Example fix

// before
{ "days": [1,2,3,4,5], "endTime": "2025-04-12T17:00:00.000Z" }
// after
{ "days": [1,2,3,4,5], "startTime": "2025-04-12T09:00:00.000Z", "endTime": "2025-04-12T17:00:00.000Z" }
Defensive patterns

Strategy: validation

Validate before calling

function validateAvailabilityInput(availability: { days: number[]; startTime?: string; endTime?: string }): string[] {
  const errors: string[] = [];
  if (!availability.startTime) errors.push('startTime is required');
  if (!availability.endTime) errors.push('endTime is required');
  return errors;
}

// Run before POST /v2/schedules (2024-04-15)
const errs = validateAvailabilityInput(item);
if (errs.length) throw new Error(errs.join(', '));

Type guard

function isValidAvailabilityInput(value: unknown): value is { days: number[]; startTime: string; endTime: string } {
  if (typeof value !== 'object' || value === null) return false;
  const v = value as Record<string, unknown>;
  return typeof v.startTime === 'string' && v.startTime.length > 0 &&
         typeof v.endTime === 'string' && v.endTime.length > 0 &&
         Array.isArray(v.days);
}

Try / catch

try {
  await api.post('/v2/schedules', { availability: [item] });
} catch (error) {
  if (error.response?.status === 400 && error.response.data.message?.includes('Missing')) {
    // Add the missing startTime or endTime field and retry
    throw new Error(`Missing required field: ${error.response.data.message}`);
  }
  throw error;
}

Prevention

When it happens

Trigger: POST /v2/schedules (2024-04-15 version) with an availability object that omits startTime or endTime; sending an empty string or null for either time field; sending a request body where the availability array items are missing the time keys entirely.

Common situations: Client SDK or frontend form doesn't include time fields when constructing the availability payload; schema mismatch after upgrading to the 2024-04-15 API version which requires startTime/endTime on every availability entry; JSON serialization drops undefined fields.

Related errors


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