{"record":{"id":"de26a3c0041367e4","repo":"iBotPeaches/Apktool","slug":"expected-start-or-end-tag","errorCode":null,"errorMessage":"Expected start or end tag.","messagePattern":"Expected start or end tag\\.","errorType":"exception","errorClass":"XmlPullParserException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryXmlResourceParser.java","lineNumber":573,"sourceCode":"        if (eventType != TEXT) {\n            throw new XmlPullParserException(\"Parser must be on TEXT or END_TAG to read text.\", this, null);\n        }\n        String result = getText();\n        eventType = next();\n        if (eventType != END_TAG) {\n            throw new XmlPullParserException(\"Event TEXT must be immediately followed by END_TAG.\", this, null);\n        }\n        return result;\n    }\n\n    @Override\n    public int nextTag() throws XmlPullParserException, IOException {\n        int eventType = next();\n        if (eventType == TEXT && isWhitespace()) {\n            eventType = next();\n        }\n        if (eventType != START_TAG && eventType != END_TAG) {\n            throw new XmlPullParserException(\"Expected start or end tag.\", this, null);\n        }\n        return eventType;\n    }\n\n    // Utility methods\n\n    private Attribute getAttribute(int index) {\n        if (mEventType != START_TAG) {\n            throw new IndexOutOfBoundsException(\"Parser must be on START_TAG to get attributes.\");\n        }\n        if (mAttributes == null || index < 0 || index >= mAttributes.length) {\n            throw new IndexOutOfBoundsException(\n                String.format(\"Attribute index out of range: index=%s, length=%s\",\n                    index, mAttributes != null ? mAttributes.length : 0));\n        }\n        return mAttributes[index];\n    }\n","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryXmlResourceParser.java#L555-L591","documentation":"nextTag() requires the next (non-whitespace-text) event to be START_TAG or END_TAG; it is the convenience method for tag-only iteration. Encountering TEXT with non-whitespace content, or END_DOCUMENT, throws this error.","triggerScenarios":"Calling nextTag() on XML that contains character data between tags (mixed content), or reaching the end of the document — e.g. unconditionally calling nextTag() in a loop that runs past the final END_TAG.","commonSituations":"Tag-walking loops like `while (parser.getEventType() != END_DOCUMENT) parser.nextTag();` that hit trailing text or EOF; parsing AXML with text nodes where the developer assumed tags only; malformed event streams.","solutions":["Bound loops on the specific END_TAG of the parent element, not just END_DOCUMENT, so nextTag() is never called at EOF.","For mixed content, use next() and filter events instead of nextTag().","Skip whitespace-only TEXT is handled internally — real text means restructure the traversal.","During development, log getEventType()/getName() before each nextTag() to find the offending position."],"exampleFix":"// before\nwhile (parser.getEventType() != XmlPullParser.END_DOCUMENT) {\n    parser.nextTag(); // throws at EOF / on text\n}\n\n// after\nparser.require(XmlPullParser.START_TAG, null, \"root\");\nwhile (parser.nextTag() == XmlPullParser.START_TAG) {\n    // handle element\n    // consume to its END_TAG:\n    while (parser.next() != XmlPullParser.END_TAG) { /* skip */ }\n}","handlingStrategy":"validation","validationCode":"int ev = parser.next();\nif (ev == XmlPullParser.TEXT && parser.isWhitespace()) ev = parser.next();\nif (ev != XmlPullParser.START_TAG && ev != XmlPullParser.END_TAG) {\n    // not tag-only content — use next() traversal instead of nextTag()\n}","typeGuard":null,"tryCatchPattern":"try {\n    int ev = parser.nextTag();\n} catch (XmlPullParserException e) {\n    if (e.getMessage().equals(\"Expected start or end tag.\")) {\n        // encountered real text or EOF — restructure the loop bounds\n    }\n}","preventionTips":["Bound nextTag() loops on the parent END_TAG, not just END_DOCUMENT.","Use next() + event filtering for mixed-content XML."],"tags":["apktool","xml-pull-parser","api-contract","axml"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}