iBotPeaches/Apktool · error · AndrolibException
Repeated type spec: pkgId=0x%02x, typeId=0x%02x, typeName=%s
Error message
Repeated type spec: pkgId=0x%02x, typeId=0x%02x, typeName=%s
What it means
AndrolibException thrown by ResPackage.addTypeSpec(typeId, typeName) when a ResTypeSpec for that typeId already exists in the package. The resource table model requires each (package, typeId) to have exactly one type spec; a second RES_TABLE_TYPE_SPEC chunk for the same typeId — or a duplicate programmatic add — triggers this.
Source
Thrown at brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResPackage.java:91
}
public boolean hasTypeSpec(int typeId) {
return mTypeSpecs.containsKey(typeId);
}
public ResTypeSpec getTypeSpec(int typeId) throws UndefinedResObjectException {
ResTypeSpec typeSpec = mTypeSpecs.get(typeId);
if (typeSpec == null) {
throw new UndefinedResObjectException(
String.format("type spec: pkgId=0x%02x, typeId=0x%02x", getId(), typeId));
}
return typeSpec;
}
public ResTypeSpec addTypeSpec(int typeId, String typeName) throws AndrolibException {
ResTypeSpec typeSpec = mTypeSpecs.get(typeId);
if (typeSpec != null) {
throw new AndrolibException(
String.format("Repeated type spec: pkgId=0x%02x, typeId=0x%02x, typeName=%s",
getId(), typeId, typeName));
}
typeSpec = new ResTypeSpec(this, typeId, typeName);
mTypeSpecs.put(typeId, typeSpec);
return typeSpec;
}
public int getTypeSpecCount() {
return mTypeSpecs.size();
}
public Collection<ResTypeSpec> listTypeSpecs() {
return mTypeSpecs.values();
}
public boolean hasType(int typeId) {View on GitHub (pinned to 79b63384d7)
Solutions
- When building a table, check hasTypeSpec(typeId) first and reuse the existing spec instead of adding again.
- For malformed APKs, verify with aapt2 dump or a reference parser; if the file truly has duplicate chunks, it is corrupt — re-obtain it.
- Decode with apktool's keep-broken-resources option only as a last resort to triage, then rebuild the arsc.
Example fix
// before ResTypeSpec spec = pkg.addTypeSpec(typeId, name); // throws on second call // after ResTypeSpec spec = pkg.hasTypeSpec(typeId) ? pkg.getTypeSpec(typeId) : pkg.addTypeSpec(typeId, name);
Defensive patterns
Strategy: validation
Validate before calling
if (pkg.hasTypeSpec(typeId)) {
ResTypeSpec spec = pkg.getTypeSpec(typeId); // reuse existing
} else {
ResTypeSpec spec = pkg.addTypeSpec(typeId, typeName);
} Try / catch
try {
pkg.addTypeSpec(typeId, typeName);
} catch (AndrolibException ex) {
// duplicate type-spec chunk in arsc -> corrupt file; report and stop parsing this package
} Prevention
- Idempotent adds: check hasTypeSpec before addTypeSpec
- Validate arsc with aapt2 dump resources when duplicates appear
- Treat duplicate chunks as tampering/corruption, not as mergeable data
When it happens
Trigger: A malformed or maliciously crafted resources.arsc containing two type-spec chunks with the same typeId; parser re-reading the same package chunk; programmatic table construction calling addTypeSpec twice for one typeId.
Common situations: APKs processed by resource obfuscators/shrinkers that merge arsc data incorrectly; hand-edited or binary-patched resource tables; duplicated library resources after bad merging by third-party tools.
Related errors
- Repeated entry spec: pkgId=0x%02x, typeId=0x%02x, entryId=0x
- 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/89441e9f3d11357f.
Report an issue: GitHub.