Tencent/tinker · error · DexException

Map is unsorted at ${previous}, ${section}

Error message

Map is unsorted at ${previous}, ${section}

What it means

Thrown by TableOfContents.readMap when consecutive map_list entries have descending file offsets — the map must list sections in ascending offset order (the spec requires it, and the sort/byteCount computation later relies on it). The message names the offending previous and current section.

Source

Thrown at third-party/aosp-dexutils/src/main/java/com/tencent/tinker/android/dex/TableOfContents.java:225

        int mapSize = in.readInt();
        Section previous = null;
        for (int i = 0; i < mapSize; i++) {
            short type = in.readShort();
            in.readShort(); // unused
            Section section = getSection(type);
            int size = in.readInt();
            int offset = in.readInt();

            if ((section.size != 0 && section.size != size)
                    || (section.off != Section.UNDEF_OFFSET && section.off != offset)) {
                throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
            }

            section.size = size;
            section.off = offset;

            if (previous != null && previous.off > section.off) {
                throw new DexException("Map is unsorted at " + previous + ", " + section);
            }

            previous = section;
        }

        header.off = 0;

        Arrays.sort(sections);

        // Skip header section, since its offset must be zero.
        for (int i = 1; i < sections.length; ++i) {
            if (sections[i].off == Section.UNDEF_OFFSET) {
                sections[i].off = sections[i - 1].off;
            }
        }
    }

    public void computeSizesFromOffsets() {

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Rebuild the dex with a conformant toolchain rather than repairing the map in place.
  2. If you write dexes, emit sections in offset order and generate the map from the final layout, never incrementally.
  3. Use `dexdump` on the input to confirm the ordering failure and identify the two sections named in the message.
Defensive patterns

Strategy: try-catch

Try / catch

catch (DexException e) with 'Map is unsorted' -> fail fast with both section names from the message; do not reorder the map yourself

Prevention

When it happens

Trigger: A map list whose entries were reordered or whose offsets were edited without re-sorting; duplicate sections with stale offsets; corrupted map data after binary edits.

Common situations: Custom dex rewriters that grow one section in place and push others around but forget to re-emit the map in order; toolchains with off-by-one offset math producing overlapping/out-of-order sections.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/a1fe0b3cc6ece2a1. Report an issue: GitHub.