{"record":{"id":"08ffa2edde4fdcbf","repo":"material-components/material-components-android","slug":"attempted-to-set-shapeappearancemodel-on-a-materia","errorCode":null,"errorMessage":"Attempted to set ShapeAppearanceModel on a MaterialButton which has an overwritten background.","messagePattern":"Attempted to set ShapeAppearanceModel on a MaterialButton which has an overwritten background\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/button/MaterialButton.java","lineNumber":1850,"sourceCode":"   */\n  public void setCheckable(boolean checkable) {\n    if (isUsingOriginalBackground()) {\n      materialButtonHelper.setCheckable(checkable);\n    }\n  }\n\n  /**\n   * Sets the {@link ShapeAppearanceModel} used for this {@link MaterialButton}'s original\n   * drawables.\n   *\n   * @throws IllegalStateException if the MaterialButton's background has been overwritten.\n   */\n  @Override\n  public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {\n    if (isUsingOriginalBackground()) {\n      materialButtonHelper.setShapeAppearance(shapeAppearanceModel);\n    } else {\n      throw new IllegalStateException(\n          \"Attempted to set ShapeAppearanceModel on a MaterialButton which has an overwritten\"\n              + \" background.\");\n    }\n  }\n\n  /**\n   * Returns the {@link ShapeAppearanceModel} used for this {@link MaterialButton}'s original\n   * drawables.\n   *\n   * <p>This {@link ShapeAppearanceModel} can be modified to change the component's shape.\n   *\n   * @throws IllegalStateException if the MaterialButton's background has been overwritten.\n   */\n  @NonNull\n  @Override\n  public ShapeAppearanceModel getShapeAppearanceModel() {\n    if (isUsingOriginalBackground()) {\n      return materialButtonHelper.getShapeAppearanceModel();","sourceCodeStart":1832,"sourceCodeEnd":1868,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/button/MaterialButton.java#L1832-L1868","documentation":"setShapeAppearanceModel() on MaterialButton delegates to MaterialButtonHelper, which can only apply a shape to the button's own original MaterialShapeDrawable background. If the background has been overwritten (isUsingOriginalBackground() at MaterialButton.java:1958 is false because materialButtonHelper.isBackgroundOverwritten()), there is no shape drawable left to mutate, so the method throws IllegalStateException instead of silently doing nothing. A background counts as overwritten when setBackground()/setBackgroundResource() (or android:background in XML) replaced the material-styled drawable.","triggerScenarios":"Declaring the button with android:background=\"@drawable/my_bg\" (or calling setBackground/setBackgroundResource on it) and later calling setShapeAppearanceModel(...). Also calling setShapeAppearanceModel after app:backgroundTint=null-style overrides that force the helper into the overwritten state.","commonSituations":"A design system wraps MaterialButton and applies a custom ripple/background drawable from XML, then app code (or a shared corner-rounding utility) tries to corners-round every button via getShapeAppearanceModel().newBuilder()...build(). Also migrating from Button to MaterialButton while keeping the old android:background attribute.","solutions":["Remove android:background / setBackground calls so the button keeps its original MaterialShapeDrawable, then set the shape through setShapeAppearanceModel().","If a custom background is required, define the shape in the background drawable itself (shape drawable / custom MaterialShapeDrawable) instead of calling setShapeAppearanceModel.","Guard the call: if (button.isUsingOriginalBackground()) — or catch IllegalStateException — before applying shared shape logic to arbitrary buttons."],"exampleFix":"<!-- before -->\n<com.google.android.material.button.MaterialButton\n    android:background=\"@drawable/custom_bg\"\n    ... />\n\n<!-- after -->\n<com.google.android.material.button.MaterialButton\n    app:backgroundTint=\"@color/custom_tint\"\n    app:strokeColor=\"@color/custom_stroke\"\n    ... />","handlingStrategy":"type-guard","validationCode":"if (button.getBackground() instanceof MaterialShapeDrawable) {\n  button.setShapeAppearanceModel(model);\n}","typeGuard":"static boolean canReshape(Button b) {\n  return b instanceof MaterialButton && b.getBackground() instanceof MaterialShapeDrawable;\n}","tryCatchPattern":"try { button.setShapeAppearanceModel(model); } catch (IllegalStateException e) { Log.w(TAG, \"background overwritten; skipping shape change\"); }","preventionTips":["Ban android:background on MaterialButton in your design-system lint rules.","Express custom looks via app:backgroundTint/strokeColor/shapeAppearance attributes instead.","Centralize shape changes in one utility that guards with instanceof before calling."],"tags":["android","material-components","materialbutton","shape","background"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}