material-components/material-components-android · error · IllegalStateException

Attempted to set ShapeAppearance on a MaterialButton which h

Error message

Attempted to set ShapeAppearance on a MaterialButton which has an overwritten background.

What it means

setShapeAppearance(ShapeAppearance) is the @RestrictTo(LIBRARY_GROUP) programmatic variant that can install a stateful shape (optionally wiring a corner SpringForce for animated corners). Like the public setShapeAppearanceModel, it only works while the button still uses its original material background; otherwise it throws IllegalStateException (MaterialButton.java:1892). Because it is library-group restricted, hitting it as an app developer usually means another Material component or a copy of library internals is calling it on your behalf.

Source

Thrown at lib/java/com/google/android/material/button/MaterialButton.java:1892

  }

  /**
   * Sets the {@link ShapeAppearance} used for this {@link MaterialButton}'s original
   * drawables.
   *
   * @throws IllegalStateException if the MaterialButton's background has been overwritten.
   * @hide
   */
  @RestrictTo(LIBRARY_GROUP)
  public void setShapeAppearance(
      @NonNull ShapeAppearance shapeAppearance) {
    if (isUsingOriginalBackground()) {
      if (materialButtonHelper.getCornerSpringForce() == null && shapeAppearance.isStateful()) {
        materialButtonHelper.setCornerSpringForce(createSpringForce());
      }
      materialButtonHelper.setShapeAppearance(shapeAppearance);
    } else {
      throw new IllegalStateException(
          "Attempted to set ShapeAppearance on a MaterialButton which has an"
              + " overwritten background.");
    }
  }

  /**
   * Returns the {@link ShapeAppearance} used for this {@link MaterialButton}'s
   * original drawables.
   *
   * <p>This {@link ShapeAppearance} can be modified to change the component's shape.
   *
   * @throws IllegalStateException if the MaterialButton's background has been overwritten.
   * @hide
   */
  @NonNull
  @RestrictTo(LIBRARY_GROUP)
  public ShapeAppearance getShapeAppearance() {
    if (isUsingOriginalBackground()) {

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Remove the android:background / setBackground override on the affected button so the original background is preserved.
  2. Reproduce with the stable released library version instead of a fork; if the crash comes from library-internal calls, file an issue with the fork/snapshot and your XML.
  3. As a last resort in a fork, guard internal setShapeAppearance calls with isUsingOriginalBackground() checks.
Defensive patterns

Strategy: validation

Validate before calling

if (button.getBackground() instanceof MaterialShapeDrawable) {
  button.setShapeAppearance(shapeAppearance);
}

Type guard

static boolean canApplyShapeAppearance(MaterialButton b) {
  return b.getBackground() instanceof MaterialShapeDrawable;
}

Try / catch

try { button.setShapeAppearance(shapeAppearance); } catch (IllegalStateException e) { Log.w(TAG, "skipping shape apply on overwritten background"); }

Prevention

When it happens

Trigger: Internal library code (or app code calling the restricted API, e.g. via reflection or a fork) invoking setShapeAppearance(shapeAppearance) on a MaterialButton whose background was replaced via android:background or setBackground(). A stateful ShapeAppearance additionally triggers creation of a corner spring force before the helper applies it.

Common situations: Using a library fork or bleeding-edge snapshot where a component (e.g. a button group or split button reshaping children) calls setShapeAppearance on child buttons that a theme or developer style gave a custom android:background. Differs from error 21 only in being the restricted/annotated entry point.

Related errors


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