iBotPeaches/Apktool · error · AndrolibException
Repeated entry spec: pkgId=0x%02x, typeId=0x%02x, entryId=0x
Error message
Repeated entry spec: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x
What it means
AndrolibException thrown by ResPackage.addEntrySpec(typeId, entryId, name) when an entry spec already exists for that resource id (after alias resolution). Each resource id may have only one entry spec; a second definition — whether from a duplicated arsc chunk or a repeated programmatic add — is rejected.
Source
Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java:191
ResEntrySpec entrySpec = mEntrySpecs.get(resId);
if (entrySpec == null) {
throw new UndefinedResObjectException(
String.format("entry spec: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x", getId(), typeId, entryId));
}
return entrySpec;
}
public ResEntrySpec addEntrySpec(int typeId, int entryId, String name) throws AndrolibException {
ResId resId = ResId.of(getId(), typeId, entryId);
if (mAliases.containsKey(resId)) {
resId = mAliases.get(resId);
typeId = resId.typeId();
entryId = resId.entryId();
}
ResEntrySpec entrySpec = mEntrySpecs.get(resId);
if (entrySpec != null) {
throw new AndrolibException(
String.format("Repeated entry spec: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x",
getId(), typeId, entryId));
}
ResTypeSpec typeSpec = getTypeSpec(typeId);
// Some apps had their entry names obfuscated or collapsed to a single value in the key string pool.
// Enforce uniqueness by forcing a rename when that happens.
if (mNameRegistry.contains(typeSpec.getName() + "/" + name)) {
name = "";
}
entrySpec = new ResEntrySpec(typeSpec, entryId, name);
mEntrySpecs.put(resId, entrySpec);
// Register the name to enforce uniqueness.
mNameRegistry.add(typeSpec.getName() + "/" + entrySpec.getName());
View on GitHub (pinned to 79b63384d7)
Solutions
- When adding programmatically, check for an existing spec first (getEntrySpec in a try/catch or maintain your own set) and reuse it.
- Treat a genuine duplicate in a parsed file as corruption — validate the arsc with aapt2 and re-obtain the APK.
- Ensure alias sources and targets do not collide with real entry ids.
Defensive patterns
Strategy: validation
Validate before calling
boolean alreadyPresent;
try { pkg.getEntrySpec(typeId, entryId); alreadyPresent = true; }
catch (UndefinedResObjectException e) { alreadyPresent = false; }
if (!alreadyPresent) pkg.addEntrySpec(typeId, entryId, name); Try / catch
try {
pkg.addEntrySpec(typeId, entryId, name);
} catch (AndrolibException ex) {
// duplicate entry spec in arsc -> corrupt file; abort package parse
} Prevention
- Make programmatic adds idempotent (probe before add)
- Keep a local set of seen resource ids when streaming the arsc
- Validate suspicious arsc files with aapt2 before parsing
When it happens
Trigger: A resources.arsc declaring the same (typeId, entryId) twice; resource-merging tools that duplicate entries; calling addEntrySpec twice for the same id; two different names mapping to one id via aliases.
Common situations: APKs post-processed by resource shrinkers/obfuscators that re-emit entry chunks; binary-patched arsc files; build pipelines merging multiple arsc files incorrectly.
Related errors
- Repeated type spec: pkgId=0x%02x, typeId=0x%02x, typeName=%s
- Repeated entry: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x,
- Stream advanced past chunk end.
- Stream advanced past chunk header end.
- Repeated overlayable: pkgId=0x%02x, name=%s
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/869858fcc19163d5.
Report an issue: GitHub.