material-components/material-components-android · error · IllegalArgumentException
Invalid state to get top offset:
Error message
Invalid state to get top offset:
What it means
BottomSheetBehavior.getTopOffsetForState(int) is an internal helper that maps a stable target state to its pixel top offset (collapsedOffset, expanded offset, halfExpandedOffset, or parentHeight for HIDDEN). Any state outside those four cases falls through the switch and throws IllegalArgumentException with the state value appended.
Source
Thrown at lib/java/com/google/android/material/bottomsheet/BottomSheetBehavior.java:2069
} else {
setStateInternal(state);
}
}
private int getTopOffsetForState(@StableState int state) {
switch (state) {
case STATE_COLLAPSED:
return collapsedOffset;
case STATE_EXPANDED:
return getExpandedOffset();
case STATE_HALF_EXPANDED:
return halfExpandedOffset;
case STATE_HIDDEN:
return parentHeight;
default:
// Fall through
}
throw new IllegalArgumentException("Invalid state to get top offset: " + state);
}
private final ViewDragHelper.Callback dragCallback =
new ViewDragHelper.Callback() {
private long viewCapturedMillis;
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
if (state == STATE_DRAGGING) {
return false;
}
if (touchingScrollingChild) {
return false;
}
if (state == STATE_EXPANDED && activePointerId == pointerId) {
View scroll;
if (multipleScrollingChildrenSupported) {View on GitHub (pinned to ac7e18efee)
Solutions
- Only use the documented constants: STATE_COLLAPSED, STATE_EXPANDED, STATE_HALF_EXPANDED, STATE_HIDDEN (and never DRAGGING/SETTLING via setState).
- Validate deserialized state values against the known set before calling setState.
- If you must store state as an int, round-trip only values obtained from the STATE_* constants.
Example fix
// before
int state = prefs.getInt("sheet_state", -1);
behavior.setState(state); // -1 -> "Invalid state to get top offset: -1"
// after
int state = prefs.getInt("sheet_state", BottomSheetBehavior.STATE_COLLAPSED);
if (state != STATE_COLLAPSED && state != STATE_EXPANDED
&& state != STATE_HALF_EXPANDED && state != STATE_HIDDEN) {
state = BottomSheetBehavior.STATE_COLLAPSED;
}
behavior.setState(state); Defensive patterns
Strategy: validation
Validate before calling
int s = readState();
if (s != STATE_COLLAPSED && s != STATE_EXPANDED && s != STATE_HALF_EXPANDED && s != STATE_HIDDEN) {
s = BottomSheetBehavior.STATE_COLLAPSED;
}
behavior.setState(s); Prevention
- Only round-trip ints obtained from STATE_* constants through storage.
- Treat any unrecognized state int as corrupt data and reset to a safe default.
When it happens
Trigger: Reaching this code via setState with an unexpected int (the setter routes stable states through getTopOffsetForState); internal calls like calculateHalfExpandedOffset when the behavior was constructed with an invalid state constant, e.g. a fabricated int passed instead of a STATE_* constant.
Common situations: Passing a raw int from storage/intent extras into setState without validating it is one of the STATE_* constants; deserializing a corrupted state value; using reflection or custom constants that collide with none of the cases.
Related errors
- STATE_DRAGGING should not be set externally.
- ratio must be a float value between 0 and 1
- offset must be greater than or equal to 0
- The view is not a child of CoordinatorLayout
- The view is not associated with BottomSheetBehavior
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/6b0d75827a886c16.
Report an issue: GitHub.