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
- Remove the android:background / setBackground override on the affected button so the original background is preserved.
- 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.
- 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
- Treat @RestrictTo(LIBRARY_GROUP) APIs as off-limits in app code; use the public setShapeAppearanceModel.
- In forks, wrap every internal setShapeAppearance call with a background-type check.
- Reproduce against stable releases to isolate fork/snapshot-only crashes.
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
- Attempted to get ShapeAppearance from a MaterialButton which
- Attempted to set ShapeAppearanceModel on a MaterialButton wh
- Attempted to get ShapeAppearanceModel from a MaterialButton
- secondaryIconGravity cannot have the same alignment as iconG
- Scroll bar must contain a child to calculate interpolation.
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/9193a520d53d939d.
Report an issue: GitHub.