material-components/material-components-android · error · IllegalArgumentException
start Month cannot be after current Month
Error message
start Month cannot be after current Month
What it means
CalendarConstraints validates its month window in the constructor: if openAt (the month the picker opens on) is set and start.compareTo(openAt) > 0 — i.e. the opening month lies before the lower bound — it throws IllegalArgumentException. The bounds must satisfy start <= openAt <= end for a coherent picker.
Source
Thrown at lib/java/com/google/android/material/datepicker/CalendarConstraints.java:74
boolean isValid(long date);
}
private CalendarConstraints(
@NonNull Month start,
@NonNull Month end,
@NonNull DateValidator validator,
@Nullable Month openAt,
int firstDayOfWeek) {
Objects.requireNonNull(start, "start cannot be null");
Objects.requireNonNull(end, "end cannot be null");
Objects.requireNonNull(validator, "validator cannot be null");
this.start = start;
this.end = end;
this.openAt = openAt;
this.firstDayOfWeek = firstDayOfWeek;
this.validator = validator;
if (openAt != null && start.compareTo(openAt) > 0) {
throw new IllegalArgumentException("start Month cannot be after current Month");
}
if (openAt != null && openAt.compareTo(end) > 0) {
throw new IllegalArgumentException("current Month cannot be after end Month");
}
if (firstDayOfWeek < 0
|| firstDayOfWeek > UtcDates.getUtcCalendar().getMaximum(Calendar.DAY_OF_WEEK)) {
throw new IllegalArgumentException("firstDayOfWeek is not valid");
}
monthSpan = start.monthsUntil(end) + 1;
yearSpan = end.year - start.year + 1;
}
boolean isWithinBounds(long date) {
return start.getDay(1) <= date && date <= end.getDay(end.daysInMonth);
}
/**
* Returns the {@link DateValidator} that determines whether a date can be clicked and selected.View on GitHub (pinned to ac7e18efee)
Solutions
- Clamp openAt into [start, end] before building: openAt = max(start, min(openAt, end)) using Month.compareTo.
- If opening month is unknown, leave openAt null (picker opens at start or today).
- When deriving openAt from a saved selection, validate the selection still satisfies current constraints first.
Example fix
// before
val constraints = CalendarConstraints.Builder()
.setStart(startMonth)
.setOpenAt(savedOpenAt) // savedOpenAt < startMonth -> throws
.build()
// after
val openAt = if (savedOpenAt != null && savedOpenAt in startMonth..endMonth) savedOpenAt else null
val constraints = CalendarConstraints.Builder()
.setStart(startMonth)
.setOpenAt(openAt)
.build() Defensive patterns
Strategy: validation
Validate before calling
fun buildConstraints(start: Month, end: Month, openAt: Month?): CalendarConstraints {
val clampedOpenAt = openAt?.let { maxOf(start, it, compareBy { it }) } // ensure openAt >= start
// simpler explicit form:
val safeOpenAt = when {
openAt == null -> null
openAt < start -> null // or start
openAt > end -> end
else -> openAt
}
return CalendarConstraints.Builder()
.setStart(start).setEnd(end).setOpenAt(safeOpenAt).build()
} Prevention
- Treat (start, openAt, end) as one invariant: start <= openAt <= end.
- Validate restored/saved months against current bounds before reuse.
- Centralize constraint construction in one helper so clamping cannot be forgotten.
When it happens
Trigger: Building CalendarConstraints via Builder with setStart(monthA) and setOpenAt(monthB) where monthB < monthA (e.g. start = today, openAt = a year ago); computing openAt from a saved selection that predates a newly configured start bound.
Common situations: Persisting a user's last-viewed month and later tightening constraints (e.g. 'no dates before today'); restoring picker state in onSaveInstanceState flows where start/end changed between sessions.
Related errors
- current Month cannot be after end Month
- firstDayOfWeek is not valid
- Only Gregorian calendars are supported.
- There must be a keyline marked as focal.
- No color resources provided for harmonization.
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/cc4a938128c030bc.
Report an issue: GitHub.