{"record":{"id":"184adabc6eec2132","repo":"material-components/material-components-android","slug":"invalid-end-icon-mode","errorCode":null,"errorMessage":"Invalid end icon mode: ","messagePattern":"Invalid end icon mode: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/textfield/EndCompoundLayout.java","lineNumber":857,"sourceCode":"        delegates.append(endIconMode, delegate);\n      }\n      return delegate;\n    }\n\n    private EndIconDelegate create(@EndIconMode int endIconMode) {\n      switch (endIconMode) {\n        case END_ICON_PASSWORD_TOGGLE:\n          return new PasswordToggleEndIconDelegate(endLayout, passwordIconDrawableId);\n        case END_ICON_CLEAR_TEXT:\n          return new ClearTextEndIconDelegate(endLayout);\n        case END_ICON_DROPDOWN_MENU:\n          return new DropdownMenuEndIconDelegate(endLayout);\n        case END_ICON_CUSTOM:\n          return new CustomEndIconDelegate(endLayout);\n        case END_ICON_NONE:\n          return new NoEndIconDelegate(endLayout);\n        default:\n          throw new IllegalArgumentException(\"Invalid end icon mode: \" + endIconMode);\n      }\n    }\n  }\n}\n","sourceCodeStart":839,"sourceCodeEnd":862,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/textfield/EndCompoundLayout.java#L839-L862","documentation":"EndCompoundLayout.getIconResId/getEndIconDelegate maps the endIconMode int to a delegate class with a switch over the END_ICON_* constants (PASSWORD_TOGGLE, CLEAR_TEXT, DROPDOWN_MENU, CUSTOM, NONE). Any int outside that set falls through to default and throws IllegalArgumentException('Invalid end icon mode: N').","triggerScenarios":"Calling setEndIconMode(rawInt) with a value not in the IntDef set, e.g. 0 from an uninitialized variable or a persisted value from an incompatible version; invalid app:endIconMode enum string in XML is caught earlier, so code paths dominate.","commonSituations":"Storing the mode as an int (settings, deep link extras) and passing it unchecked; using a constant name that exists in a newer Material version than the one on the classpath.","solutions":["Use only TextInputLayout.END_ICON_* constants when calling setEndIconMode.","Validate/normalize persisted ints to a known constant before setting (default to END_ICON_NONE).","Match constant usage to your Material library version."],"exampleFix":"// before\ntil.setEndIconMode(modeFromConfig); // e.g. 42 -> throws\n\n// after\nint mode = (modeFromConfig >= TextInputLayout.END_ICON_NONE\n    && modeFromConfig <= TextInputLayout.END_ICON_DROPDOWN_MENU)\n        ? modeFromConfig : TextInputLayout.END_ICON_NONE;\ntil.setEndIconMode(mode);","handlingStrategy":"type-guard","validationCode":"private static final Set<Integer> VALID_END_ICON_MODES = Set.of(\n    TextInputLayout.END_ICON_NONE,\n    TextInputLayout.END_ICON_CUSTOM,\n    TextInputLayout.END_ICON_PASSWORD_TOGGLE,\n    TextInputLayout.END_ICON_CLEAR_TEXT,\n    TextInputLayout.END_ICON_DROPDOWN_MENU);\n\nif (VALID_END_ICON_MODES.contains(mode)) til.setEndIconMode(mode);","typeGuard":"private boolean isValidEndIconMode(int mode) {\n  return mode >= TextInputLayout.END_ICON_NONE && mode <= TextInputLayout.END_ICON_DROPDOWN_MENU;\n}","tryCatchPattern":null,"preventionTips":["Only pass TextInputLayout.END_ICON_* constants.","Annotate wrapper params with @TextInputLayout.EndIconMode for compile-time checks.","Normalize persisted ints to END_ICON_NONE by default."],"tags":["textinputlayout","validation","icons","android"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}