material-components/material-components-android · error · IllegalArgumentException
offset must be greater than or equal to 0
Error message
offset must be greater than or equal to 0
What it means
BottomSheetBehavior.setExpandedOffset(int) sets the top offset in pixels of the sheet in STATE_EXPANDED when fitToContents is false. Offsets are measured downward from the parent top, so only values >= 0 are valid; a negative offset throws IllegalArgumentException.
Source
Thrown at lib/java/com/google/android/material/bottomsheet/BottomSheetBehavior.java:1201
*/
@FloatRange(from = 0.0f, to = 1.0f)
public float getHalfExpandedRatio() {
return halfExpandedRatio;
}
/**
* Determines the top offset of the BottomSheet in the {@link #STATE_EXPANDED} state when
* fitsToContent is false. The default value is 0, which results in the sheet matching the
* parent's top.
*
* @param offset an integer value greater than equal to 0, representing the {@link
* #STATE_EXPANDED} offset. Value must not exceed the offset in the half expanded state.
* @attr ref
* com.google.android.material.R.styleable#BottomSheetBehavior_Layout_behavior_expandedOffset
*/
public void setExpandedOffset(int offset) {
if (offset < 0) {
throw new IllegalArgumentException("offset must be greater than or equal to 0");
}
this.expandedOffset = offset;
updateDrawableForTargetState(state, /* animate= */ true);
}
/**
* Returns the current expanded offset. If {@code fitToContents} is true, it will automatically
* pick the offset depending on the height of the content.
*
* @attr ref
* com.google.android.material.R.styleable#BottomSheetBehavior_Layout_behavior_expandedOffset
*/
public int getExpandedOffset() {
return fitToContents
? fitToContentsOffset
: Math.max(expandedOffset, paddingTopSystemWindowInsets ? 0 : insetTop);
}
View on GitHub (pinned to ac7e18efee)
Solutions
- Pass 0 (default, sheet matches parent top) or a positive pixel offset.
- Fix inset math: offset = Math.max(0, desiredTopInsetPx) rather than allowing negative intermediates.
- Note the value must also not exceed the half-expanded offset — keep the two settings consistent.
Example fix
// before int offset = topInset - peekHeight; // can be negative behavior.setExpandedOffset(offset); // after behavior.setExpandedOffset(Math.max(0, topInset));
Defensive patterns
Strategy: validation
Validate before calling
int offset = Math.max(0, computedExpandedOffset); behavior.setExpandedOffset(offset);
Prevention
- Do inset arithmetic with clamping at the boundary.
- Keep expandedOffset <= half-expanded offset to stay consistent.
When it happens
Trigger: Calling setExpandedOffset(-1) or any negative pixel value; computing the offset from status bar / window inset arithmetic that evaluates negative on edge-case devices; reading the offset from a dimension that resolves negative.
Common situations: Subtracting insets (getStatusBarHeight(), WindowInsets) in the wrong order so the result goes below zero; treating the offset as 'distance upward from the bottom' rather than 'distance downward from the top'; copying a negative value from old layout XML after a refactor.
Related errors
- ratio must be a float value between 0 and 1
- Color names need to be at least four and correspond to attri
- cradleVerticalOffset must be positive.
- STATE_DRAGGING should not be set externally.
- Invalid state to get top offset:
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/6cc3ff1ef09e43a8.
Report an issue: GitHub.