{"record":{"id":"bb791675adb2f532","repo":"calcom/cal.diy","slug":"the-event-type-can-t-be-booked-at-the-start-time","errorCode":null,"errorMessage":"The event type can't be booked at the \"start\" time provided. This could be because it's too soon (violating the minimum booking notice) or too far in the future (outside the event's scheduling window). Try fetching available slots first using the GET /v2/slots endpoint and then make a booking with \"start\" time equal to one of the available slots.","messagePattern":"The event type can't be booked at the \"start\" time provided\\. This could be because it's too soon \\(violating the minimum booking notice\\) or too far in the future \\(outside the event's scheduling window\\)\\. Try fetching available slots first using the GET /v2/slots endpoint and then make a booking with \"start\" time equal to one of the available slots\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/errors.service.ts","lineNumber":44,"sourceCode":"    if (body.teamSlug && body.eventTypeSlug && body.organizationSlug) {\n      throw new NotFoundException(\n        `Event type with slug ${body.eventTypeSlug} belonging to team ${body.teamSlug} within organization ${body.organizationSlug} not found.`\n      );\n    }\n    throw new NotFoundException(`Event type with id ${body.eventTypeId} not found.`);\n  }\n\n  handleBookingError(error: unknown, bookingTeamEventType: boolean): never {\n    const hostsUnavaile = \"One of the hosts either already has booking at this time or is not available\";\n\n    if (error instanceof Error) {\n      if (error.message === \"no_available_users_found_error\") {\n        if (bookingTeamEventType) {\n          throw new BadRequestException(hostsUnavaile);\n        }\n        throw new BadRequestException(\"User either already has booking at this time or is not available\");\n      } else if (error.message === \"booking_time_out_of_bounds_error\") {\n        throw new BadRequestException(\n          `The event type can't be booked at the \"start\" time provided. This could be because it's too soon (violating the minimum booking notice) or too far in the future (outside the event's scheduling window). Try fetching available slots first using the GET /v2/slots endpoint and then make a booking with \"start\" time equal to one of the available slots.`\n        );\n      } else if (error.message === \"Attempting to book a meeting in the past.\") {\n        throw new BadRequestException(\"Attempting to book a meeting in the past.\");\n      } else if (error.message === \"hosts_unavailable_for_booking\") {\n        throw new BadRequestException(hostsUnavaile);\n      } else if (error.message === \"booker_limit_exceeded_error\") {\n        throw new BadRequestException(\n          \"Attendee with this email can't book because the maximum number of active bookings has been reached.\"\n        );\n      } else if (error.message === \"booker_limit_exceeded_error_reschedule\") {\n        const errorData =\n          \"data\" in error ? (error.data as { rescheduleUid: string }) : { rescheduleUid: undefined };\n        let message =\n          \"Attendee with this email can't book because the maximum number of active bookings has been reached.\";\n        if (errorData?.rescheduleUid) {\n          message += ` You can reschedule your existing booking (${errorData.rescheduleUid}) to a new timeslot instead.`;\n        }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/errors.service.ts#L26-L62","documentation":"Thrown by handleBookingError when the booking engine raised 'booking_time_out_of_bounds_error'. BadRequestException (HTTP 400). It means the requested start violates the event type's minimum booking notice or its scheduling window (future limit). The message points the caller to GET /v2/slots to obtain valid start times.","triggerScenarios":"Booking with a start time closer than the event type's minimumBookingNotice (e.g. booking 5 minutes out when notice is 24h), or further out than the event type's booking window (e.g. 6 months ahead when the window is 30 days). The engine throws booking_time_out_of_bounds_error and the service maps it to this guidance.","commonSituations":"Reduced minimumBookingNotice on the event type without updating the client; timezone mismatch making 'now' appear hours away; far-future bookings for planning that exceed the window; changed event-type scheduling window after the client cached an old slot.","solutions":["Always fetch GET /v2/slots first and book a start time it returns.","Check the event type's minimumBookingNotice and bookingWindow and ensure start is within bounds client-side.","If the slot list is empty for the desired window, widen the window or reduce the notice.","Re-fetch the event type after config changes to refresh cached bounds."],"exampleFix":"// before\nstart = dayjs().add(10, 'minute').toISOString();  // below 24h notice\n\n// after\nconst slots = await api.get(`/v2/slots?eventTypeId=${eventTypeId}&startTime=${dayjs().toISOString()}&endTime=${dayjs().add(14,'day').toISOString()}`);\nstart = slots.data.slots[0]?.start;","handlingStrategy":"validation","validationCode":"const et = await api.get(`/v2/event-types/${eventTypeId}`);\nconst minNoticeMs = (et.data.minimumBookingNotice ?? 0) * 1000;\nconst windowMs = (et.data.bookingWindow ?? Infinity) * 24*60*60*1000;\nconst startMs = new Date(body.start).getTime();\nif (startMs < Date.now() + minNoticeMs || startMs > Date.now() + windowMs) throw new Error('start out of bounds');","typeGuard":"null","tryCatchPattern":"try { await api.post('/v2/bookings', body); }\ncatch (e) {\n  if (e.response?.status === 400 && /can't be booked at the .start. time/.test(e.response.data.message)) {\n    /* re-fetch slots and use a returned start */\n  } else throw e;\n}","preventionTips":["Always fetch GET /v2/slots and book a returned start.","Re-fetch the event type after minimumBookingNotice or bookingWindow changes.","Validate start is within notice+window client-side before POSTing."],"tags":["api","bookings","availability","scheduling-window","minimum-notice","nestjs"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}