material-components/material-components-android · error · IllegalArgumentException
Invalid state to get outer edge offset: %d
Error message
Invalid state to get outer edge offset: %d
What it means
SideSheetBehavior.getOuterEdgeOffsetForState() throws IllegalArgumentException for any state other than STATE_EXPANDED and STATE_HIDDEN. It maps a stable target state to the pixel offset the sheet should settle to; transient states (DRAGGING/SETTLING) and any other int have no target offset, hence the rejection.
Source
Thrown at lib/java/com/google/android/material/sidesheet/SideSheetBehavior.java:781
* {@link StateSettlingTracker}.
*/
private boolean isSettling(View child, int state, boolean isReleasingView) {
int left = getOuterEdgeOffsetForState(state);
ViewDragHelper viewDragHelper = getViewDragHelper();
return viewDragHelper != null
&& (isReleasingView
? viewDragHelper.settleCapturedViewAt(left, child.getTop())
: viewDragHelper.smoothSlideViewTo(child, left, child.getTop()));
}
int getOuterEdgeOffsetForState(@StableSheetState int state) {
switch (state) {
case STATE_EXPANDED:
return getExpandedOffset();
case STATE_HIDDEN:
return sheetDelegate.getHiddenOffset();
default:
throw new IllegalArgumentException("Invalid state to get outer edge offset: " + state);
}
}
@Nullable
ViewDragHelper getViewDragHelper() {
return viewDragHelper;
}
private final ViewDragHelper.Callback dragCallback =
new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
if (state == STATE_DRAGGING) {
return false;
}
return viewRef != null && viewRef.get() == child;
}View on GitHub (pinned to ac7e18efee)
Solutions
- Restrict state arguments to BottomSheetBehavior.STATE_EXPANDED and STATE_HIDDEN when driving side sheets.
- Validate any restored/persisted state before calling state APIs: map unknown values to a safe default.
- Do not port BottomSheetDialog state constants (e.g. half-expanded) to SideSheetBehavior.
Example fix
// before
behavior.setState(savedState); // savedState could be STATE_DRAGGING/SETTLING/other
// after
int safe = (savedState == BottomSheetBehavior.STATE_HIDDEN)
? BottomSheetBehavior.STATE_HIDDEN
: BottomSheetBehavior.STATE_EXPANDED;
behavior.setState(safe); Defensive patterns
Strategy: type-guard
Validate before calling
static int safeSheetState(int state) {
return state == BottomSheetBehavior.STATE_HIDDEN
? BottomSheetBehavior.STATE_HIDDEN
: BottomSheetBehavior.STATE_EXPANDED;
} Type guard
/** SideSheet state APIs accept only EXPANDED and HIDDEN. */
static boolean isSideSheetTargetState(int state) {
return state == BottomSheetBehavior.STATE_EXPANDED
|| state == BottomSheetBehavior.STATE_HIDDEN;
} Prevention
- Don't port BottomSheet state constants (half-expanded, dragging) into side-sheet code.
- Validate restored state ints before calling any state-mapping API.
When it happens
Trigger: Calling this package-visible method (or a code path that uses it, like setState on an unlaid-out view with an invalid state) with e.g. STATE_DRAGGING, STATE_SETTLING, STATE_HALF_EXPANDED, or a custom int.
Common situations: Reusing a state int from BottomSheetBehavior code that includes half-expanded semantics; passing a state restored from a bundle without validation; test code poking internal offsets with arbitrary states.
Related errors
- Invalid sheet edge position value: %d. Must be %d or %d.
- STATE_%s should not be set externally.
- There must be a keyline marked as focal.
- No color resources provided for harmonization.
- Theme overlay should be used with the accompanying int[] att
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/bd218956d2ae30e3.
Report an issue: GitHub.