vuetifyjs/vuetify · error · Error

End date is earlier than start date.

Error message

End date is earlier than start date.

What it means

Thrown by createDayList() in VCalendar when getDayIdentifier(end) < getDayIdentifier(start). The day identifier is YYYYMMDD as a number, so this is a pure date-ordering check independent of time. The function builds the visible day range for a calendar view and cannot iterate backwards.

Source

Thrown at packages/vuetify/src/components/VCalendar/util/timestamp.ts:440

  return new Date(`${date}T${time}:00+00:00`)
}

export function createDayList (
  start: CalendarTimestamp,
  end: CalendarTimestamp,
  now: CalendarTimestamp,
  weekdaySkips: number[],
  max = 42,
  min = 0
): CalendarTimestamp[] {
  const stop = getDayIdentifier(end)
  const days: CalendarTimestamp[] = []
  let current = copyTimestamp(start)
  let currentIdentifier = 0
  let stopped = currentIdentifier === stop

  if (stop < getDayIdentifier(start)) {
    throw new Error('End date is earlier than start date.')
  }

  while ((!stopped || days.length < min) && days.length < max) {
    currentIdentifier = getDayIdentifier(current)
    stopped = stopped || currentIdentifier === stop
    if (weekdaySkips[current.weekday] === 0) {
      current = nextDay(current)
      continue
    }
    const day = copyTimestamp(current)
    updateFormatted(day)
    updateRelative(day, now)
    days.push(day)
    current = relativeDays(current, nextDay, weekdaySkips[current.weekday])
  }

  if (!days.length) throw new Error('No dates found using specified start date, end date, and weekdays.')

View on GitHub (pinned to 8d153908df)

Solutions

  1. Verify start <= end at the call site before invoking createDayList.
  2. Compare getDayIdentifier(start) and getDayIdentifier(end) and swap or reject when inverted.
  3. Check the component props (start/end) that feed the calendar; correct the binding direction.
  4. Ensure timezone conversion happens before identifier computation so the day boundaries align.

Example fix

// before
const days = createDayList(start, end, now, weekdaySkips)

// after
import { getDayIdentifier } from 'vuetify/util/timestamp'
if (getDayIdentifier(end) < getDayIdentifier(start)) {
  throw new RangeError(`end ${end.date} before start ${start.date}`)
}
const days = createDayList(start, end, now, weekdaySkips)
Defensive patterns

Strategy: validation

Validate before calling

import { getDayIdentifier, createDayList, type CalendarTimestamp } from 'vuetify/util/timestamp'

function safeDayList(start: CalendarTimestamp, end: CalendarTimestamp, now: CalendarTimestamp, skips: number[]) {
  if (getDayIdentifier(end) < getDayIdentifier(start)) {
    throw new RangeError(`end ${end.date} is before start ${start.date}`)
  }
  return createDayList(start, end, now, skips)
}

Type guard

import { getDayIdentifier, type CalendarTimestamp } from 'vuetify/util/timestamp'
function isOrderedRange(start: CalendarTimestamp, end: CalendarTimestamp): boolean {
  return getDayIdentifier(start) <= getDayIdentifier(end)
}

Try / catch

try {
  return createDayList(start, end, now, skips)
} catch (e) {
  if (e instanceof Error && /earlier than start date/.test(e.message)) {
    // swap and retry, or return empty
    return createDayList(end, start, now, skips)
  }
  throw e
}

Prevention

When it happens

Trigger: Calling createDayList with a start timestamp whose date is after the end timestamp's date. In components this comes from props where `start` and `end` resolve to inverted dates (e.g. start='2024-01-31', end='2024-01-01'), or when a weekday-skew/interval miscalculation produces an end before start.

Common situations: Swapping start/end prop bindings, off-by-one in a custom range picker, timezone shifts that move the end date backwards across the day boundary, or feeding a manually-constructed CalendarTimestamp whose year/month/day are inconsistent.

Related errors


AI-assisted analysis of vuetifyjs/vuetify@8d153908df (2026-08-12). Data as JSON: /api/errors/d6ac8ea0f231fc90. Report an issue: GitHub.