{"record":{"id":"53fe1d3f0ada2ee4","repo":"material-components/material-components-android","slug":"we-already-have-an-edittext-can-only-have-one","errorCode":null,"errorMessage":"We already have an EditText, can only have one","messagePattern":"We already have an EditText, can only have one","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/textfield/TextInputLayout.java","lineNumber":1510,"sourceCode":"      onProvideAutofillStructure(structure, flags);\n      onProvideAutofillVirtualStructure(structure, flags);\n\n      structure.setChildCount(inputFrame.getChildCount());\n      for (int i = 0; i < inputFrame.getChildCount(); i++) {\n        View child = inputFrame.getChildAt(i);\n        ViewStructure childStructure = structure.newChild(i);\n        child.dispatchProvideAutofillStructure(childStructure, flags);\n        if (child == editText) {\n          childStructure.setHint(getHint());\n        }\n      }\n    }\n  }\n\n  private void setEditText(EditText editText) {\n    // If we already have an EditText, throw an exception\n    if (this.editText != null) {\n      throw new IllegalArgumentException(\"We already have an EditText, can only have one\");\n    }\n\n    if (getEndIconMode() != END_ICON_DROPDOWN_MENU && !(editText instanceof TextInputEditText)) {\n      Log.i(\n          LOG_TAG,\n          \"EditText added is not a TextInputEditText. Please switch to using that\"\n              + \" class instead.\");\n    }\n\n    this.editText = editText;\n    if (minEms != NO_WIDTH) {\n      setMinEms(minEms);\n    } else {\n      setMinWidth(minWidth);\n    }\n    if (maxEms != NO_WIDTH) {\n      setMaxEms(maxEms);\n    } else {","sourceCodeStart":1492,"sourceCodeEnd":1528,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/textfield/TextInputLayout.java#L1492-L1528","documentation":"TextInputLayout is a container that wraps exactly one EditText. When a second EditText is added — either via XML (two EditText tags inside TextInputLayout) or programmatically through addView/setEditText — the private setEditText(TextInputLayout.java:1510) throws IllegalArgumentException because the internal this.editText field is already set. The library uses this single-editText invariant everywhere (hint, counter, error label all bind to that one field).","triggerScenarios":"Declaring two EditText (or TextInputEditText) elements as direct children of one TextInputLayout in a layout XML; calling textInputLayout.addView(editText) a second time; inflating a layout where programmatic code adds an EditText to a TextInputLayout that already absorbed one from XML.","commonSituations":"Copy-pasting a layout block and forgetting to remove the old EditText; dynamically swapping input fields (e.g. switching email -> username) by adding a new EditText instead of reconfiguring the existing one; merging layouts with <include> that each contain an EditText inside the same TextInputLayout.","solutions":["Ensure the TextInputLayout has exactly one EditText/TextInputEditText as a direct child in XML.","If swapping fields at runtime, keep one EditText and change its inputType/text instead of adding another.","If you truly need two inputs, use two separate TextInputLayout wrappers.","If adding programmatically, remove the previous EditText from the TextInputLayout before adding the new one."],"exampleFix":"<!-- before -->\n<com.google.android.material.textfield.TextInputLayout ...>\n    <com.google.android.material.textfield.TextInputEditText ... />\n    <EditText ... /> <!-- second child: crashes -->\n</com.google.android.material.textfield.TextInputLayout>\n\n<!-- after -->\n<com.google.android.material.textfield.TextInputLayout ...>\n    <com.google.android.material.textfield.TextInputEditText ... />\n</com.google.android.material.textfield.TextInputLayout>\n<!-- and a second TextInputLayout for the other field -->","handlingStrategy":"validation","validationCode":"boolean hasExactlyOneEditText(TextInputLayout til) {\n  int editTextCount = 0;\n  for (int i = 0; i < til.getChildCount(); i++) {\n    if (til.getChildAt(i) instanceof EditText) editTextCount++;\n  }\n  return editTextCount == 1;\n}\n// call before programmatically adding another EditText:\nif (hasExactlyOneEditText(til)) throw new IllegalStateException(\"TextInputLayout already has an EditText\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep exactly one EditText per TextInputLayout in XML; review layouts after copy-paste edits.","To swap inputs at runtime, mutate inputType/hint on the existing EditText rather than adding a new one.","Treat lint/layout-inspection warnings about unexpected children in TextInputLayout as build errors."],"tags":["android","material-components","textinputlayout","xml-layout","view-hierarchy"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}