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

  1. Always use the constants MaterialTimePicker.INPUT_MODE_KEYBOARD or MaterialTimePicker.INPUT_MODE_CLOCK.
  2. Validate any dynamically sourced mode: if (mode != INPUT_MODE_KEYBOARD && mode != INPUT_MODE_CLOCK) mode = INPUT_MODE_CLOCK;
  3. 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

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


AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14). Data as JSON: /api/errors/302e0e7e848a0006. Report an issue: GitHub.