calcom/cal.diy · error · BadRequestException
Provided 'slotDuration' is not one of the possible lengths f
Error message
Provided 'slotDuration' is not one of the possible lengths for the event type. The possible lengths for this variable length event type are: ${eventTypeMetadata.multipleDuration.join(", ")} What it means
Thrown by SlotsService.validateSlotDuration when reserving or updating a slot for a variable-length event type. Variable-length event types store their allowed durations as a number array in eventType.metadata.multipleDuration; the slotDuration you pass must be an element of that array or the request is rejected as a 400 BadRequest. The message dynamically lists the valid values so the client can correct the input.
Source
Thrown at apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots.service.ts:225
);
if (overlappingReservation) {
throw new UnprocessableEntityException(
`This time slot is already reserved by another user. Please choose a different time.`
);
}
}
validateSlotDuration(eventType: EventType, inputSlotDuration: number) {
const eventTypeMetadata = eventTypeMetadataSchema.parse(eventType.metadata);
if (!eventTypeMetadata?.multipleDuration) {
throw new BadRequestException(
"You passed 'slotDuration' but this event type is not a variable length event type."
);
}
if (!eventTypeMetadata.multipleDuration.includes(inputSlotDuration)) {
throw new BadRequestException(
`Provided 'slotDuration' is not one of the possible lengths for the event type. The possible lengths for this variable length event type are: ${eventTypeMetadata.multipleDuration.join(
", "
)}`
);
}
}
async canSpecifyCustomReservationDuration(authUserId: number, eventType: EventType) {
if (eventType.userId) {
return await this.canSpecifyCustomReservationDurationIndividualEvent(authUserId, eventType.userId);
}
if (eventType.teamId) {
return await this.canSpecifyCustomReservationDurationTeamEvent(authUserId, eventType.teamId);
}
return false;
}
async canSpecifyCustomReservationDurationIndividualEvent(authUserId: number, eventTypeOwnerId: number) {View on GitHub (pinned to 176037d0af)
Solutions
- Fetch the event type first and read metadata.multipleDuration (exposed as lengthInMinutesOptions), then pass only a value present in that array.
- If any valid duration is acceptable, omit slotDuration entirely so the service falls back to eventType.length.
- Update the event type's metadata.multipleDuration to include the desired duration before reserving.
Example fix
// before
body: { eventTypeId, slotStart, slotDuration: 20 }
// after
const et = await api.getEventType(eventTypeId);
const allowed = et.lengthInMinutesOptions ?? [et.length];
const slotDuration = allowed.includes(20) ? 20 : et.length;
body: { eventTypeId, slotStart, slotDuration } Defensive patterns
Strategy: validation
Validate before calling
import type { EventType } from './types';
function pickSlotDuration(
et: Pick<EventType, 'length' | 'lengthInMinutesOptions'>,
requested?: number
): number | undefined {
if (requested === undefined) return undefined; // fall back to event type length
const allowed = et.lengthInMinutesOptions ?? [];
return allowed.includes(requested) ? requested : undefined;
}
// usage:
// const slotDuration = pickSlotDuration(eventType, body.slotDuration);
// if (body.slotDuration && slotDuration === undefined) { /* warn user */ } Type guard
function isValidSlotDuration(
et: { multipleDuration?: number[]; length: number },
value: number
): boolean {
const allowed = et.multipleDuration ?? [et.length];
return allowed.includes(value);
} Try / catch
try {
await api.reserveSlot({ eventTypeId, slotStart, slotDuration });
} catch (e) {
if (e.status === 400 && /possible lengths/.test(e.message)) {
// parse allowed list from message, reprompt user to pick a valid duration
} else throw e;
} Prevention
- Always derive the duration picker options from lengthInMinutesOptions on the fetched event type, never hardcode them.
- When the event type is edited, invalidate any cached duration lists in the client.
- Omit slotDuration when you want the event type's default length rather than guessing a value.
When it happens
Trigger: POST /v2/event-types/{eventTypeId}/slots or PATCH /v2/slots/{uid} with a body containing slotDuration: 20 on an event type whose metadata.multipleDuration is [15,30,45]. The event type IS variable-length (multipleDuration exists), so the earlier 'not a variable length event type' guard is skipped, but 20 is not in the array.
Common situations: A UI dropdown of durations is desynced from the event type's configured multipleDuration after an admin edited the event type. An integration hardcodes a duration (e.g. 30) that was later removed from the event type. A client caches the duration list and sends a stale value after the event type was updated.
Related errors
- Event Type not found
- 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
- 'to' must not be before 'from'
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/2b73333e4827960f.
Report an issue: GitHub.