{"record":{"id":"bc796a89970a5871","repo":"material-components/material-components-android","slug":"unable-to-create-badge","errorCode":null,"errorMessage":"Unable to create badge","messagePattern":"Unable to create badge","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/tabs/TabLayout.java","lineNumber":2867,"sourceCode":"                  .inflate(R.layout.design_layout_tab_text, this, false);\n      addView(textView);\n    }\n\n    /**\n     * Creates an instance of {@link BadgeDrawable} if none exists. Initializes (if needed) and\n     * returns the associated instance of {@link BadgeDrawable}.\n     *\n     * @return an instance of BadgeDrawable associated with {@code Tab}.\n     */\n    @NonNull\n    private BadgeDrawable getOrCreateBadge() {\n      // Creates a new instance if one is not already initialized for this TabView.\n      if (badgeDrawable == null) {\n        badgeDrawable = BadgeDrawable.create(getContext());\n      }\n      tryUpdateBadgeAnchor();\n      if (badgeDrawable == null) {\n        throw new IllegalStateException(\"Unable to create badge\");\n      }\n      return badgeDrawable;\n    }\n\n    @Nullable\n    private BadgeDrawable getBadge() {\n      return badgeDrawable;\n    }\n\n    private void removeBadge() {\n      if (badgeAnchorView != null) {\n        tryRemoveBadgeFromAnchor();\n      }\n      badgeDrawable = null;\n    }\n\n    private void addOnLayoutChangeListener(@Nullable final View view) {\n      if (view == null) {","sourceCodeStart":2849,"sourceCodeEnd":2885,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/tabs/TabLayout.java#L2849-L2885","documentation":"TabView.getOrCreateBadge() lazily creates a BadgeDrawable (BadgeDrawable.create(context)) and anchors it; the code then re-checks badgeDrawable != null and throws IllegalStateException('Unable to create badge') if creation still yielded null. This is a defensive assertion: BadgeDrawable.create is not expected to return null, so hitting it means badge creation was unexpectedly impossible in this environment.","triggerScenarios":"Calling tab.getOrCreateBadge() (or getBadge/tryUpdateBadgeAnchor paths that route through it) in an environment where BadgeDrawable.create returns null — effectively unreachable in stock Material versions; realistic only with modified/overridden badge creation or unusual runtime instrumentation.","commonSituations":"Forks or shadows of the Material library where BadgeDrawable.create was altered; test environments/mocking frameworks that stub BadgeDrawable.create to return null.","solutions":["Ensure the stock com.google.android.material dependency is used (no forks shadowing BadgeDrawable).","If mocking in tests, do not stub BadgeDrawable.create to return null (use real instances or returnsSmartNulls).","Report upstream if it reproduces with an unmodified library — it indicates a Material internals defect."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  BadgeDrawable badge = tab.getOrCreateBadge();\n  badge.setVisible(true);\n} catch (IllegalStateException e) {\n  // Badge creation unexpectedly failed; degrade gracefully (no badge) and log.\n  Log.w(TAG, \"Badge unavailable for tab\", e);\n}","preventionTips":["Do not fork or shadow BadgeDrawable.create.","In unit tests, avoid mocking that stubs BadgeDrawable.create to null.","Call getOrCreateBadge lazily right before configuring the badge."],"tags":["tablayout","badge","defensive-check","android"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}