Tencent/tinker · critical · IllegalStateException

Illegal dex format, there's at least one loop in class inher

Error message

Illegal dex format, there's at least one loop in class inheritance graph.

What it means

IllegalStateException from ClassDefSectionPatchAlgorithm's topological sort: after Kahn's algorithm over the class inheritance graph (superclass/interface type-id edges), fewer classes were emitted than exist — meaning the graph has a cycle. A legal dex cannot have cyclic inheritance, so the input dex is invalid.

Source

Thrown at tinker-commons/src/main/java/com/tencent/tinker/commons/dexpatcher/algorithms/patch/ClassDefSectionPatchAlgorithm.java:145

        }

        final List<ClassDef> result = new ArrayList<>();
        while (!typeIdWithZeroInDegrees.isEmpty()) {
            final int currentTypeId = typeIdWithZeroInDegrees.poll();
            result.add(typeIdToClassDefMap.get(currentTypeId));

            for (int nextTypeId : typeGraph.get(currentTypeId)) {
                final int newInDegree = inDegrees.get(nextTypeId) - 1;
                inDegrees.put(nextTypeId, newInDegree);
                if (newInDegree == 0) {
                    typeIdWithZeroInDegrees.offer(nextTypeId);
                }
            }
        }

        // Check if type graph contains loop.
        if (result.size() != elements.size()) {
            throw new IllegalStateException("Illegal dex format, there's at least one loop in class inheritance graph.");
        }

        return result;
    }
}

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Validate the dex with standard tooling (dexdump/baksmali) and rebuild the offending module
  2. Exclude the corrupt dex from patching if only one is affected
  3. Report a Tinker issue with the dex if it passes standard validation yet still cycles
Defensive patterns

Strategy: try-catch

Try / catch

try {
    // dex diff/patch
} catch (IllegalStateException e) {
    if (String.valueOf(e.getMessage()).contains("loop in class inheritance graph")) {
        // input dex is invalid: quarantine it and report
    } else { throw e; }
}

Prevention

When it happens

Trigger: Diffing or patching a dex whose class_def items form a superclass cycle (class A extends B, B extends A), which the sort in sortTypeListByInheritanceDetection cannot order.

Common situations: Malformed dex produced by experimental toolchains or protectors; hand-edited dex; corrupted dex where type indices point at wrong entries.

Related errors


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