{"record":{"id":"e08345ea60513904","repo":"Tencent/tinker","slug":"cannot-merge-dex-files-that-do-not-contain-a-map","errorCode":null,"errorMessage":"Cannot merge dex files that do not contain a map","messagePattern":"Cannot merge dex files that do not contain a map","errorType":"exception","errorClass":"DexException","httpStatus":null,"severity":"error","filePath":"third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java","lineNumber":188,"sourceCode":"            throw new DexException(\"Unexpected magic: \" + Arrays.toString(magic));\n        }\n\n        checksum = headerIn.readInt();\n        signature = headerIn.readByteArray(20);\n        fileSize = headerIn.readInt();\n        int headerSize = headerIn.readInt();\n        if (headerSize != SizeOf.HEADER_ITEM) {\n            throw new DexException(\"Unexpected header: 0x\" + Integer.toHexString(headerSize));\n        }\n        int endianTag = headerIn.readInt();\n        if (endianTag != DexFormat.ENDIAN_TAG) {\n            throw new DexException(\"Unexpected endian tag: 0x\" + Integer.toHexString(endianTag));\n        }\n        linkSize = headerIn.readInt();\n        linkOff = headerIn.readInt();\n        mapList.off = headerIn.readInt();\n        if (mapList.off == 0) {\n            throw new DexException(\"Cannot merge dex files that do not contain a map\");\n        }\n        stringIds.size = headerIn.readInt();\n        stringIds.off = headerIn.readInt();\n        typeIds.size = headerIn.readInt();\n        typeIds.off = headerIn.readInt();\n        protoIds.size = headerIn.readInt();\n        protoIds.off = headerIn.readInt();\n        fieldIds.size = headerIn.readInt();\n        fieldIds.off = headerIn.readInt();\n        methodIds.size = headerIn.readInt();\n        methodIds.off = headerIn.readInt();\n        classDefs.size = headerIn.readInt();\n        classDefs.off = headerIn.readInt();\n        dataSize = headerIn.readInt();\n        dataOff = headerIn.readInt();\n    }\n\n    private void readMap(Dex.Section in) throws IOException {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java#L170-L206","documentation":"Thrown by TableOfContents.readHeader when map_off (the map_list file offset at header offset 52) is 0. The message text ('Cannot merge dex files that do not contain a map') reveals the primary consumer: dex merging needs the map list to enumerate sections; without it the table of contents cannot be built.","triggerScenarios":"new Dex()/TableOfContents.readFrom on a dex whose map_off was zeroed — typically produced by nonstandard writers (some proguard/older dx edge cases, stripped dexes) or by patch tools that rewrite the header and clear map_off.","commonSituations":"Dexes that load fine on ART (the runtime is lazier about the map) but fail Tinker-style patch generation, which fully parses the TOC; header corruption after binary edits.","solutions":["Rebuild the offending dex with a mainstream toolchain (d8/dx) which always emits a map list.","If the dex is a build intermediate, find the upstream step that stripped or never wrote mapList and disable that stripping.","As a diagnostic, hexdump offset 52 — if it's zero while other header fields look sane, the file was post-processed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"static boolean hasMapList(ByteBuffer b) { return b.getInt(52) != 0; } // map_off","typeGuard":null,"tryCatchPattern":"catch (DexException e) with 'do not contain a map' -> rebuild the dex with d8; do not attempt merge of map-less inputs","preventionTips":["In build pipelines, always run the final dex through d8 (not just ART-loadable tooling) so map-less outputs are caught at build time."],"tags":["dex","map-list","merge","header","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}