{"record":{"id":"adb4fc54e380cc52","repo":"iBotPeaches/Apktool","slug":"repeated-overlayable-pkgid-0x-02x-name-s","errorCode":null,"errorMessage":"Repeated overlayable: pkgId=0x%02x, name=%s","messagePattern":"Repeated overlayable: pkgId=0x%02x, name=(.+?)","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java","lineNumber":314,"sourceCode":"    }\n\n    public boolean hasOverlayable(String name) {\n        return mOverlayables.containsKey(name);\n    }\n\n    public ResOverlayable getOverlayable(String name) throws UndefinedResObjectException {\n        ResOverlayable overlayable = mOverlayables.get(name);\n        if (overlayable == null) {\n            throw new UndefinedResObjectException(\n                String.format(\"overlayable: pkgId=0x%02x, name=%s\", getId(), name));\n        }\n        return overlayable;\n    }\n\n    public ResOverlayable addOverlayable(String name, String actor) throws AndrolibException {\n        ResOverlayable overlayable = mOverlayables.get(name);\n        if (overlayable != null) {\n            throw new AndrolibException(\n                String.format(\"Repeated overlayable: pkgId=0x%02x, name=%s\", getId(), name));\n        }\n\n        overlayable = new ResOverlayable(this, name, actor);\n        mOverlayables.put(name, overlayable);\n        return overlayable;\n    }\n\n    public int getOverlayableCount() {\n        return mOverlayables.size();\n    }\n\n    public Collection<ResOverlayable> listOverlayables() {\n        return mOverlayables.values();\n    }\n\n    public boolean isAlias(ResId resId) {\n        return mAliases.containsKey(resId);","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java#L296-L332","documentation":"AndrolibException thrown by ResPackage.addOverlayable(name, actor) when an overlayable with that name already exists in the package. Overlayable names must be unique per package; a second <overlayable> declaration with the same name in resources.arsc, or a repeated programmatic add, triggers this.","triggerScenarios":"An arsc containing two overlayable chunks with the same name; merging resource tables that each declared the overlayable; calling addOverlayable twice for one name during table construction.","commonSituations":"Obfuscated or merged APKs where overlayable blocks were duplicated by processing tools; binary-patched arsc files; refactors that append rather than replace overlayable declarations.","solutions":["Check hasOverlayable(name) first and reuse the existing overlayable.","Treat genuine duplicates in a parsed file as corruption; validate with aapt2 and re-obtain the APK.","When generating arsc programmatically, keep a single source of truth for overlayable declarations."],"exampleFix":"// before\nResOverlayable o = pkg.addOverlayable(name, actor); // throws if exists\n\n// after\nResOverlayable o = pkg.hasOverlayable(name) ? pkg.getOverlayable(name) : pkg.addOverlayable(name, actor);","handlingStrategy":"validation","validationCode":"if (!pkg.hasOverlayable(name)) {\n    pkg.addOverlayable(name, actor);\n} // else reuse pkg.getOverlayable(name)","typeGuard":null,"tryCatchPattern":"try {\n    pkg.addOverlayable(name, actor);\n} catch (AndrolibException ex) {\n    // duplicate overlayable declaration -> corrupt arsc; report\n}","preventionTips":["Make adds idempotent via hasOverlayable","Emit each overlayable once when generating arsc","Validate duplicated declarations with aapt2 dump"],"tags":["android","apktool","resource-table","overlayable","duplicate"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}