{"record":{"id":"40ad532a1a0e42fe","repo":"Tencent/tinker","slug":"unexpected-map-value-for-0x-type","errorCode":null,"errorMessage":"Unexpected map value for 0x${type}","messagePattern":"Unexpected map value for 0x(.+?)","errorType":"exception","errorClass":"DexException","httpStatus":null,"severity":"error","filePath":"third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java","lineNumber":218,"sourceCode":"        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 {\n        int mapSize = in.readInt();\n        Section previous = null;\n        for (int i = 0; i < mapSize; i++) {\n            short type = in.readShort();\n            in.readShort(); // unused\n            Section section = getSection(type);\n            int size = in.readInt();\n            int offset = in.readInt();\n\n            if ((section.size != 0 && section.size != size)\n                    || (section.off != Section.UNDEF_OFFSET && section.off != offset)) {\n                throw new DexException(\"Unexpected map value for 0x\" + Integer.toHexString(type));\n            }\n\n            section.size = size;\n            section.off = offset;\n\n            if (previous != null && previous.off > section.off) {\n                throw new DexException(\"Map is unsorted at \" + previous + \", \" + section);\n            }\n\n            previous = section;\n        }\n\n        header.off = 0;\n\n        Arrays.sort(sections);\n\n        // Skip header section, since its offset must be zero.\n        for (int i = 1; i < sections.length; ++i) {","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java#L200-L236","documentation":"Thrown by TableOfContents.readMap when a map_list entry's size or offset disagrees with what was already recorded — either a nonzero value read earlier from the header (stringIds/classDefs/etc. are populated from the header before the map is read) or a duplicate map item giving different numbers. The map and the header must be consistent.","triggerScenarios":"Parsing a dex where the header's *_ids size/offset fields contradict the corresponding map entries, or the same section type appears twice in the map with different values — hallmarks of hand-edited or corrupt binaries, or buggy dex writers that fill the header and map independently.","commonSituations":"Post-processing tools (rewriters, hot-patch injectors) that update the map but not the header, or vice versa; dexes assembled by concatenating sections without reconciling both structures.","solutions":["Regenerate the dex with d8/dx; both header and map are then written consistently.","If you must patch dexes binary-wise, always update both the header fields and the map entries (and the checksum/signature) atomically.","Validate inputs with `dexdump -f` which cross-checks header/map consistency and pinpoints the offending section type."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"null // full header/map cross-check requires parsing; cheap pre-check is `dexdump -f` in CI on every input dex","typeGuard":null,"tryCatchPattern":"catch (DexException e) with 'Unexpected map value' -> reject input, require regeneration; record the type code from the message for triage","preventionTips":["Run `dexdump` as a CI gate on dexes entering merge steps.","If you must rewrite dex bytes, update header + map + checksum + signature in one atomic pass with a tested library."],"tags":["dex","map-list","consistency","corruption","tinker"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}