{"record":{"id":"8371fa3dd56692f6","repo":"iBotPeaches/Apktool","slug":"missing-type-string-pool","errorCode":null,"errorMessage":"Missing type string pool.","messagePattern":"Missing type string pool\\.","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryResourceParser.java","lineNumber":303,"sourceCode":"                    break;\n                default:\n                    skipUnexpectedChunk(parser);\n                    break;\n            }\n        }\n\n        // Clean up.\n        injectDummyEntrySpecs();\n        mInvalidConfigs.clear();\n        mPackage = null;\n        mTypeIdOffset = 0;\n        mTypeStringPool = null;\n        mKeyStringPool = null;\n    }\n\n    private void parseTypeSpec(ResChunkPullParser parser) throws AndrolibException, IOException {\n        if (mTypeStringPool == null) {\n            throw new AndrolibException(\"Missing type string pool.\");\n        }\n\n        // ResTable_typeSpec\n        int id = mIn.readUnsignedByte();\n        mIn.skipByte(); // res0\n        mIn.skipShort(); // typesCount\n        int entryCount = mIn.readInt();\n\n        skipUnreadHeader(parser);\n\n        if (mEntrySpecFlagsOffsets != null) {\n            mEntrySpecFlagsOffsets.add(Pair.of(mIn.position(), entryCount));\n        }\n        mIn.skipBytes(entryCount * 4); // flags\n\n        mPackage.addTypeSpec(id, mTypeStringPool.getString(id - 1));\n    }\n","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/BinaryResourceParser.java#L285-L321","documentation":"parseTypeSpec requires the package's type-name string pool to be loaded before any RES_TABLE_TYPE_SPEC chunk can be interpreted (it maps the spec's type id to a name via `mTypeStringPool.getString(id - 1)`). If a type spec chunk appears before the RES_TABLE_TYPE_TYPE string-pool chunk in the package, this error is thrown.","triggerScenarios":"Decoding an arsc where the RES_TABLE_TYPE_SPEC chunk precedes the type string pool chunk inside a package — i.e. chunk order violates the aapt2 format, typically from a corrupted, hand-edited, or packer-mangled resources.arsc.","commonSituations":"Resources obfuscated by third-party packers (e.g. commercial Android packers) that strip or reorder string pools; arsc patched by resource-shrinking tools with bugs; malformed arsc emitted by non-standard build tooling.","solutions":["Confirm the APK decodes with stock aapt2 (`aapt2 dump resources app.apk`) — if that also fails, the arsc itself is malformed.","Get the original unobfuscated APK (different device ABI split, pre-packing source) and decode that.","If you control the arsc generation, emit the type string pool (RES_TABLE_TYPE_TYPE) before any type spec chunks.","Report apps protected by packers as unsupported rather than trying to hand-patch pool offsets."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    apkDecoder.decode(apk, out);\n} catch (AndrolibException e) {\n    if (e.getMessage().contains(\"type string pool\")) {\n        // arsc chunk order is invalid (packer/obfuscator) — try an unobfuscated source\n    }\n}","preventionTips":["Treat 'string pool' errors as structural arsc damage, not as configuration bugs.","Prefer APK sources that skip third-party packers.","When generating arsc, keep canonical aapt2 chunk ordering."],"tags":["apktool","arsc","parsing","chunk-order","obfuscation"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}