{"record":{"id":"d5f09d839b3fae2a","repo":"iBotPeaches/Apktool","slug":"repeated-package-group-id-0x-02x-name-s","errorCode":null,"errorMessage":"Repeated package group: id=0x%02x, name=%s","messagePattern":"Repeated package group: id=0x%02x, name=(.+?)","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResTable.java","lineNumber":161,"sourceCode":"        }\n    }\n\n    public boolean hasPackageGroup(int id) {\n        return mPackageGroups.containsKey(id);\n    }\n\n    public ResPackageGroup getPackageGroup(int id) throws UndefinedResObjectException {\n        ResPackageGroup pkgGroup = mPackageGroups.get(id);\n        if (pkgGroup == null) {\n            throw new UndefinedResObjectException(String.format(\"package group: id=0x%02x\", id));\n        }\n        return pkgGroup;\n    }\n\n    public ResPackageGroup addPackageGroup(int id, String name) throws AndrolibException {\n        ResPackageGroup pkgGroup = mPackageGroups.get(id);\n        if (pkgGroup != null) {\n            throw new AndrolibException(String.format(\"Repeated package group: id=0x%02x, name=%s\", id, name));\n        }\n\n        // If the package ID is 0x00 and the main package is loaded, that means that a shared library is being loaded,\n        // so we change it to the reference package ID defined in the dynamic reference table, or assign it the next\n        // available ID.\n        if (id == 0 && mMainPackage != null) {\n            id = getDynamicRefPackageId(name);\n            if (id == 0) {\n                do {\n                    id = mNextPackageId++;\n                } while (mDynamicRefTable.containsKey(id));\n            }\n        }\n\n        pkgGroup = new ResPackageGroup(this, id, name);\n        mPackageGroups.put(id, pkgGroup);\n        return pkgGroup;\n    }","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResTable.java#L143-L179","documentation":"ResTable.addPackageGroup throws when a package group with the same package ID is registered twice while loading a resource table. This means the APK (or APK plus loaded framework/library tables) declares two packages that map to the same 0xNN package ID, which the table cannot represent.","triggerScenarios":"Loading an APK whose resources.arsc contains duplicated package chunks with the same ID, or loading an APK whose package ID collides with an already-loaded framework/shared-library package (e.g. a renamed or repackaged framework-res injected into the APK).","commonSituations":"Decoding vendor/OEM APKs that bundle their own framework resources, decoding an APK against a custom framework installed with the same package ID, or processing APKs that were merged/rewritten by other tools producing duplicate package chunks.","solutions":["Update to the latest apktool release; duplicate-package handling has been improved over versions","Decode with a clean framework setup: `apktool empty-framework-dir` then reinstall the correct framework (`apktool if framework-res.apk`) for the device's Android version","If a custom framework tag is in play, make sure you are not loading two frameworks with the same package ID (use `-t` with distinct tags)","Inspect the APK: `aapt dump resources app.apk` or unzip resources.arsc and check for repeated package chunks; if the APK itself is malformed, obtain the original"],"exampleFix":"# before\napktool d app.apk   # fails: Repeated package group: id=0x01\n\n# after\napktool empty-framework-dir\napktool if framework-res.apk   # pulled from the same device/ROM\napktool d app.apk","handlingStrategy":"validation","validationCode":"// Dump package IDs before full decode to spot duplicates\n// `aapt dump resources app.apk | head` — look for repeated Package Groups\n// or with apktool: decode with `--force-manifest` / verbose logging and inspect\n// For programmatic use, load the table once in a probe:\ntry {\n    ResTable probe = new ResTable(new Config());\n    probe.loadPackageGroups ?? null; // full load will throw early with the duplicate id in the message\n} catch (AndrolibException e) { /* message contains offending id */ }","typeGuard":null,"tryCatchPattern":"try {\n    decoder.decode(apk, out);\n} catch (AndrolibException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Repeated package group\")) {\n        // message shows the colliding id; clean framework dir and retry once with correct framework\n    } else { throw e; }\n}","preventionTips":["Keep framework cache per device/ROM using -t tags instead of mixing","Run `apktool empty-framework-dir` when switching between ROMs","Use current apktool releases which handle more package layouts"],"tags":["apktool","resources-arsc","package-id","framework"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}