{"record":{"id":"4862bffc06052e87","repo":"iBotPeaches/Apktool","slug":"repeated-alias-pkgid-0x-02x-aliasid-s","errorCode":null,"errorMessage":"Repeated alias: pkgId=0x%02x, aliasId=%s","messagePattern":"Repeated alias: pkgId=0x%02x, aliasId=(.+?)","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java","lineNumber":346,"sourceCode":"        return mOverlayables.values();\n    }\n\n    public boolean isAlias(ResId resId) {\n        return mAliases.containsKey(resId);\n    }\n\n    public ResId resolveAlias(ResId aliasId) throws UndefinedResObjectException {\n        ResId resId = mAliases.get(aliasId);\n        if (resId == null) {\n            throw new UndefinedResObjectException(\n                String.format(\"alias: pkgId=0x%02x, aliasId=%s\", getId(), aliasId));\n        }\n        return resId;\n    }\n\n    public void addAlias(ResId aliasId, ResId finalId) throws AndrolibException {\n        if (mAliases.containsKey(aliasId)) {\n            throw new AndrolibException(\n                String.format(\"Repeated alias: pkgId=0x%02x, aliasId=%s\", getId(), aliasId));\n        }\n\n        mAliases.put(aliasId, finalId);\n    }\n\n    public int getAliasCount() {\n        return mAliases.size();\n    }\n\n    public Map<ResId, ResId> getAliases() {\n        return mAliases;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"ResPackage{id=0x%02x, name=%s}\", getId(), getName());\n    }","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java#L328-L364","documentation":"AndrolibException thrown by ResPackage.addAlias(aliasId, finalId) when the alias id is already mapped in mAliases. Aliases redirect one resource id to another (common in obfuscated/collapsed resource tables); each alias id may be registered only once. Note the sibling resolveAlias throws 'alias: pkgId=..., aliasId=...' (error in the same SOURCE block) when looking up an unregistered alias.","triggerScenarios":"An arsc with two alias definitions for the same source id; programmatic table construction registering the same alias twice; alias chains where an id is both alias and target mapped repeatedly.","commonSituations":"Resource-obfuscation output (collapsed ids) with duplicated mapping entries; merged or patched arsc files; rebuild tools replaying alias registration.","solutions":["Before addAlias, check getAliases().containsKey(aliasId) and skip or update instead of re-adding.","For parsed files, a genuine duplicate alias indicates corruption — validate with aapt2 and re-obtain the APK.","Keep alias generation deterministic (sort/dedupe) when emitting arsc yourself."],"exampleFix":"// before\npkg.addAlias(aliasId, finalId); // throws if already mapped\n\n// after\nif (!pkg.getAliases().containsKey(aliasId)) {\n    pkg.addAlias(aliasId, finalId);\n}","handlingStrategy":"validation","validationCode":"if (!pkg.getAliases().containsKey(aliasId)) {\n    pkg.addAlias(aliasId, finalId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    pkg.addAlias(aliasId, finalId);\n} catch (AndrolibException ex) {\n    // duplicate alias mapping -> corrupt or replayed table; report\n}","preventionTips":["Check getAliases() before registering an alias","Dedupe alias tables when emitting arsc","Do not re-parse into an already populated ResPackage"],"tags":["android","apktool","resource-table","alias","duplicate","obfuscation"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}