material-components/material-components-android · error · IllegalArgumentException
no button data for mode: > mode <
Error message
no button data for mode: > mode <
What it means
MaterialTimePicker.getButtonDataForMode (MaterialTimePicker.java:458) maps the picker's input mode to icon/tooltip data for the mode-toggle button. The switch only handles INPUT_MODE_KEYBOARD (0) and INPUT_MODE_CLOCK (1); any other int falls through to the default branch and throws IllegalArgumentException. This indicates the mode value was never produced by the library's own constants.
Source
Thrown at lib/java/com/google/android/material/timepicker/MaterialTimePicker.java:458
timePickerTextInputPresenter.clearCheck();
return timePickerTextInputPresenter;
}
private ModeButtonData getModeButtonData(@InputMode int mode) {
switch (mode) {
case INPUT_MODE_KEYBOARD:
return new ModeButtonData(
clockIcon,
R.string.material_timepicker_clock_mode_description,
R.string.material_timepicker_clock_mode_tooltip);
case INPUT_MODE_CLOCK:
return new ModeButtonData(
keyboardIcon,
R.string.material_timepicker_text_input_mode_description,
R.string.material_timepicker_text_input_mode_tooltip);
default:
throw new IllegalArgumentException("no button data for mode: " + mode);
}
}
@Nullable
TimePickerClockPresenter getTimePickerClockPresenter() {
return timePickerClockPresenter;
}
@VisibleForTesting
void setActivePresenter(@Nullable TimePickerPresenter presenter) {
activePresenter = presenter;
}
/** The supplied listener is called when the user confirms a valid selection. */
public boolean addOnPositiveButtonClickListener(@NonNull OnClickListener listener) {
return positiveButtonListeners.add(listener);
}
View on GitHub (pinned to ac7e18efee)
Solutions
- Always use the constants MaterialTimePicker.INPUT_MODE_KEYBOARD or MaterialTimePicker.INPUT_MODE_CLOCK.
- Validate any dynamically sourced mode: if (mode != INPUT_MODE_KEYBOARD && mode != INPUT_MODE_CLOCK) mode = INPUT_MODE_CLOCK;
- When persisting/restoring mode, sanitize on read with Math.max(0, Math.min(1, mode)) or an explicit whitelist check.
Example fix
// before
picker.setMode(prefs.getInt("time_mode", 3)); // 3 is invalid
// after
int mode = prefs.getInt("time_mode", MaterialTimePicker.INPUT_MODE_CLOCK);
if (mode != MaterialTimePicker.INPUT_MODE_CLOCK && mode != MaterialTimePicker.INPUT_MODE_KEYBOARD) {
mode = MaterialTimePicker.INPUT_MODE_CLOCK;
}
picker.setMode(mode); Defensive patterns
Strategy: validation
Validate before calling
static int sanitizeTimePickerMode(int mode) {
return (mode == MaterialTimePicker.INPUT_MODE_KEYBOARD
|| mode == MaterialTimePicker.INPUT_MODE_CLOCK)
? mode
: MaterialTimePicker.INPUT_MODE_CLOCK;
}
picker.setMode(sanitizeTimePickerMode(rawMode)); Try / catch
try { picker.setMode(mode); } catch (IllegalArgumentException e) { picker.setMode(MaterialTimePicker.INPUT_MODE_CLOCK); } // last-resort only; prefer pre-validation Prevention
- Never hardcode mode ints; use MaterialTimePicker.INPUT_MODE_* constants.
- Sanitize persisted/bundled modes on read.
- Wrap picker construction behind one factory that validates mode centrally.
When it happens
Trigger: Calling materialTimePicker.setMode(someInt) with a value outside 0/1 and then showing the picker (the mode-toggle button is built when the picker UI is constructed); passing a mode read from bundle/state that was corrupted or hand-computed; reflection or a custom saved-state round-trip writing an invalid mode.
Common situations: Hardcoding a mode int instead of using MaterialTimePicker.INPUT_MODE_CLOCK / INPUT_MODE_KEYBOARD; persisting mode in savedInstanceState with a stale value after a library constant change; passing a value obtained from an enum ordinal of the wrong enum.
Related errors
- Invalid fade mode: > fadeMode <
- Invalid fit mode: > fitMode <
- Invalid transition direction: > transitionDirection <
- Invalid axis: > axis <
- Invalid motion path type: > pathInt <
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/302e0e7e848a0006.
Report an issue: GitHub.