material-components/material-components-android · error · IllegalArgumentException

The wrap overflow mode is not compatible to the vertical…

Error message

The wrap overflow mode is not compatible to the vertical orientation.

What it means

MaterialButtonGroup (the flow/overflow-aware button group) supports an OVERFLOW_MODE_WRAP mode in which buttons that do not fit horizontally wrap onto additional rows. Wrapping only makes sense for horizontal groups: in onMeasure (MaterialButtonGroup.java:382) a vertical orientation with wrap overflow throws IllegalArgumentException, because 'wrapping' a vertical column of buttons has no defined meaning and would break the group's child-shape stitching and overflow-menu logic.

Solutions

  1. Use a different overflow mode for vertical groups — keep the default OVERFLOW_MODE_OVERFLOW (overflow menu) or whatever non-wrap value fits — i.e. remove app:overflowMode="wrap".
  2. Keep the group horizontal if you need wrapping; vertical wrapping layouts are better expressed by FlexboxLayout or a Flow helper.
  3. If orientation is switched at runtime, call setOverflowMode back to a compatible value before changing orientation.

Example fix

<!-- before -->
<com.google.android.material.button.MaterialButtonGroup
    app:orientation="vertical"
    app:overflowMode="wrap" />

<!-- after -->
<com.google.android.material.button.MaterialButtonGroup
    app:orientation="vertical" />
Defensive patterns

Strategy: validation

Validate before calling

if (group.getOrientation() == LinearLayout.HORIZONTAL) {
  group.setOverflowMode(MaterialButtonGroup.OVERFLOW_MODE_WRAP);
} else {
  group.setOverflowMode(MaterialButtonGroup.OVERFLOW_MODE_OVERFLOW);
}

Prevention

When it happens

Trigger: Setting app:overflowMode="wrap" (or setOverflowMode(OVERFLOW_MODE_WRAP)) on a MaterialButtonGroup whose orientation is vertical (XML app:orientation="vertical" or setOrientation(VERTICAL)). The check runs inside onMeasure, so the exception is thrown at layout time, not at attribute-set time.

Common situations: Copying a horizontal wrap-mode button row from a demo and flipping it to vertical without removing the wrap overflow mode. Toggling orientation at runtime based on screen size while leaving overflowMode=wrap. Because the throw happens in onMeasure, the stack trace points at layout/inflation rather than the misconfigured attribute, which confuses developers.

Related errors


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

Appendix: source

Thrown at lib/java/com/google/android/material/button/MaterialButtonGroup.java:382

  @NonNull
  public ShapeAppearanceModel getChildOriginalShapeAppearanceModel(int index) {
    return originalChildShapeAppearanceModels.get(index).getDefaultShape();
  }

  private void recoverAllChildrenLayoutParams() {
    for (int i = 0; i < getChildCount(); i++) {
      MaterialButton child = getChildButton(i);
      child.recoverOriginalLayoutParams();
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    adjustChildMarginsAndUpdateLayout();
    int wrappedHeight = 0;
    if (overflowMode == OVERFLOW_MODE_WRAP) {
      if (getOrientation() == VERTICAL) {
        throw new IllegalArgumentException(
            "The wrap overflow mode is not compatible to the vertical orientation.");
      }
      if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) {
        throw new IllegalArgumentException(
            "The wrap overflow mode is not compatible with wrap_content layout width.");
      }
      wrappedHeight = maybeWrapButtons(widthMeasureSpec, heightMeasureSpec);
    }
    maybeUpdateOverflowMenu(widthMeasureSpec, heightMeasureSpec);
    updateChildShapes();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    if (overflowMode == OVERFLOW_MODE_WRAP && wrappedHeight != getMeasuredHeight()) {
      setMeasuredDimension(getMeasuredWidth(), wrappedHeight);
    }
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {

View on GitHub (pinned to ac7e18efee)