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

  1. When building a table, check hasTypeSpec(typeId) first and reuse the existing spec instead of adding again.
  2. For malformed APKs, verify with aapt2 dump or a reference parser; if the file truly has duplicate chunks, it is corrupt — re-obtain it.
  3. 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

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


AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14). Data as JSON: /api/errors/89441e9f3d11357f. Report an issue: GitHub.