iBotPeaches/Apktool · error · AndrolibException
Repeated entry: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x,
Error message
Repeated entry: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x, config=%s
What it means
AndrolibException thrown by ResPackage.addEntry(typeId, entryId, config, value) when an entry already exists for the (resource id, config) pair (after alias resolution). Each resource may hold one value per configuration; a second value for the same config — from a duplicated arsc entry chunk or repeated programmatic add — is rejected.
Source
Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java:270
return entry;
}
public ResEntry addEntry(int typeId, int entryId, ResValue value) throws AndrolibException {
return addEntry(typeId, entryId, ResConfig.DEFAULT, value);
}
public ResEntry addEntry(int typeId, int entryId, ResConfig config, ResValue value) throws AndrolibException {
ResId resId = ResId.of(getId(), typeId, entryId);
if (mAliases.containsKey(resId)) {
resId = mAliases.get(resId);
typeId = resId.typeId();
entryId = resId.entryId();
}
Pair<ResId, ResConfig> entryKey = Pair.of(resId, config);
ResEntry entry = mEntries.get(entryKey);
if (entry != null) {
throw new AndrolibException(
String.format("Repeated entry: pkgId=0x%02x, typeId=0x%02x, entryId=0x%04x, config=%s",
getId(), typeId, entryId, config));
}
ResEntrySpec entrySpec = getEntrySpec(typeId, entryId);
Pair<Integer, ResConfig> typeKey = Pair.of(typeId, config);
ResType type = mTypes.get(typeKey);
if (type == null) {
// We can safely create the type if it's missing.
ResTypeSpec typeSpec = getTypeSpec(typeId);
type = new ResType(typeSpec, config);
mTypes.put(typeKey, type);
}
entry = new ResEntry(type, entrySpec, value);
mEntries.put(entryKey, entry);
return entry;
}View on GitHub (pinned to 79b63384d7)
Solutions
- When building programmatically, check mEntries via a get in try/catch (or track added ids) before addEntry.
- Do not re-run a parser over an already-loaded ResPackage; create a fresh ResTable for each parse.
- Validate suspicious files with aapt2 dump resources to confirm duplicates, then re-obtain the APK.
Defensive patterns
Strategy: validation
Validate before calling
// When streaming entries, track seen (id, config) keys
Set<Pair<ResId, ResConfig>> seen = new HashSet<>();
Pair<ResId, ResConfig> key = Pair.of(resId, config);
if (!seen.add(key)) { /* duplicate chunk in arsc: report corruption */ } Try / catch
try {
pkg.addEntry(typeId, entryId, config, value);
} catch (AndrolibException ex) {
// repeated entry chunk -> corrupt arsc; stop parsing this package
} Prevention
- Parse each arsc into a fresh ResTable; never replay over a populated one
- Dedupe (id, config) while generating arsc yourself
- Validate merges with aapt2 before shipping
When it happens
Trigger: A resources.arsc containing two RES_TABLE_ENTRY blocks for the same id and config; parsers visiting the same type chunk twice; programmatic builds calling addEntry twice for one (id, config).
Common situations: Obfuscators/collapsers that rewrite arsc entry lists; merged or binary-patched resource tables; replaying a parse over an already-populated ResPackage.
Related errors
- Repeated type spec: pkgId=0x%02x, typeId=0x%02x, typeName=%s
- Repeated entry spec: pkgId=0x%02x, typeId=0x%02x, entryId=0x
- 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/e014236acef1e05a.
Report an issue: GitHub.