{"record":{"id":"3f481e2c5b5f611b","repo":"material-components/material-components-android","slug":"attempted-to-get-shapeappearancemodel-from-a-mater","errorCode":null,"errorMessage":"Attempted to get ShapeAppearanceModel from a MaterialButton which has an overwritten background.","messagePattern":"Attempted to get ShapeAppearanceModel from 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":1870,"sourceCode":"              + \" 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();\n    } else {\n      throw new IllegalStateException(\n          \"Attempted to get ShapeAppearanceModel from a MaterialButton which has an overwritten\"\n              + \" background.\");\n    }\n  }\n\n  /**\n   * Sets the {@link ShapeAppearance} used for this {@link MaterialButton}'s original\n   * drawables.\n   *\n   * @throws IllegalStateException if the MaterialButton's background has been overwritten.\n   * @hide\n   */\n  @RestrictTo(LIBRARY_GROUP)\n  public void setShapeAppearance(\n      @NonNull ShapeAppearance shapeAppearance) {\n    if (isUsingOriginalBackground()) {\n      if (materialButtonHelper.getCornerSpringForce() == null && shapeAppearance.isStateful()) {\n        materialButtonHelper.setCornerSpringForce(createSpringForce());","sourceCodeStart":1852,"sourceCodeEnd":1888,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/button/MaterialButton.java#L1852-L1888","documentation":"getShapeAppearanceModel() is the read counterpart of setShapeAppearanceModel(): it returns the ShapeAppearanceModel of the button's original shape drawable. When the background was replaced (isUsingOriginalBackground() false), no such model exists, so MaterialButton throws IllegalStateException (MaterialButton.java:1870) rather than returning null or a fabricated default. This keeps the get/set API symmetric — both fail on an overwritten background.","triggerScenarios":"Calling button.getShapeAppearanceModel() (e.g. to read current corner sizes before modifying them) on a MaterialButton inflated with android:background set, or after code called setBackground/setBackgroundResource on it.","commonSituations":"Utility code that walks a view hierarchy and 'reads then tweaks' every MaterialButton's corners. Team A ships a themed button style with a custom android:background; team B's corner-customization helper calls getShapeAppearanceModel() and crashes at runtime only for those styles.","solutions":["Remove the android:background override (use app:backgroundTint, app:strokeColor, app:strokeWidth, app:shapeAppearance instead) so the original background survives.","Make the utility defensive: check the button's background is a MaterialShapeDrawable or wrap the call in try/catch IllegalStateException before falling back to a fixed corner radius.","If a custom drawable is unavoidable, track the intended shape separately (e.g. in the style/tag) instead of reading it from the button."],"exampleFix":"// before\nShapeAppearanceModel model = button.getShapeAppearanceModel(); // throws if background overwritten\n\n// after\nif (button.getBackground() instanceof MaterialShapeDrawable) {\n  ShapeAppearanceModel model = button.getShapeAppearanceModel();\n  button.setShapeAppearanceModel(model.toBuilder().setAllCornerSizes(24f).build());\n} else {\n  button.setBackground(createRoundedBackground(24f));\n}","handlingStrategy":"type-guard","validationCode":"if (button.getBackground() instanceof MaterialShapeDrawable) {\n  ShapeAppearanceModel model = button.getShapeAppearanceModel();\n}","typeGuard":"static boolean hasOriginalShape(Button b) {\n  return b.getBackground() instanceof MaterialShapeDrawable;\n}","tryCatchPattern":"try { return button.getShapeAppearanceModel(); } catch (IllegalStateException e) { return ShapeAppearanceModel.builder().setAllCornerSizes(0).build(); }","preventionTips":["Never read the shape model of buttons inflated from arbitrary layouts without a background-type check.","Keep custom backgrounds out of MaterialButton styles.","Store intended corner radii in the style/tag rather than reverse-engineering them from the view."],"tags":["android","material-components","materialbutton","shape","background"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}