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

  1. Pass 0 (default, sheet matches parent top) or a positive pixel offset.
  2. Fix inset math: offset = Math.max(0, desiredTopInsetPx) rather than allowing negative intermediates.
  3. 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

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


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