skylot/jadx · error · JadxRuntimeException
Iterative traversal limit reached: limit: {}, visitor: {}, b
Error message
Iterative traversal limit reached: limit: {}, visitor: {}, blocks count: {} What it means
Thrown as JadxRuntimeException by DepthRegionTraversal.traverseIterative() (and traverseIncludingExcHandlers) when an iterative region visitor requests re-traversal more than 5 times the number of basic blocks in the method. Iterative visitors return a boolean 'repeat' indicating they made structural changes and want another pass; a limit prevents infinite loops from visitors that always report changes. The limit is ITERATIVE_LIMIT_MULTIPLIER (5) multiplied by the method's basic block count.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraversal.java:49
traverseInternal(mth, visitor, container);
}
public static <R> @Nullable R traversePartial(MethodNode mth, IRegionPartialVisitor<R> visitor) {
return traversePartialInternal(mth, visitor, mth.getRegion());
}
public static <R> @Nullable R traversePartial(MethodNode mth, IContainer container, IRegionPartialVisitor<R> visitor) {
return traversePartialInternal(mth, visitor, container);
}
public static void traverseIterative(MethodNode mth, IRegionIterativeVisitor visitor) {
boolean repeat;
int k = 0;
int limit = ITERATIVE_LIMIT_MULTIPLIER * mth.getBasicBlocks().size();
do {
repeat = traverseIterativeStepInternal(mth, visitor, mth.getRegion());
if (k++ > limit) {
throw new JadxRuntimeException("Iterative traversal limit reached: "
+ "limit: " + limit + ", visitor: " + visitor.getClass().getName()
+ ", blocks count: " + mth.getBasicBlocks().size());
}
} while (repeat);
}
public static void traverseIncludingExcHandlers(MethodNode mth, IRegionIterativeVisitor visitor) {
boolean repeat;
int k = 0;
int limit = ITERATIVE_LIMIT_MULTIPLIER * mth.getBasicBlocks().size();
do {
repeat = traverseIterativeStepInternal(mth, visitor, mth.getRegion());
if (!repeat) {
for (ExceptionHandler h : mth.getExceptionHandlers()) {
repeat = traverseIterativeStepInternal(mth, visitor, h.getHandlerRegion());
if (repeat) {
break;
}View on GitHub (pinned to e738a26571)
Solutions
- Report to jadx developers with the input file, the visitor class name from the error message, and the block count.
- Try the latest jadx version — convergence bugs in region visitors are frequently patched.
- As a workaround, use --decompilation-mode that uses simpler region processing, or skip specific visitors via debug flags.
- If developing jadx, inspect the named visitor class for oscillation bugs — ensure it returns true only when it actually made a net structural change.
Defensive patterns
Strategy: try-catch
Try / catch
try {
DepthRegionTraversal.traverseIterative(mth, visitor);
} catch (JadxRuntimeException e) {
if (e.getMessage().contains("Iterative traversal limit reached")) {
LOG.warn("Visitor {} did not converge for method {} ({} blocks), skipping",
visitor.getClass().getSimpleName(), mth, mth.getBasicBlocks().size());
// Continue decompilation without this visitor's transformations
} else {
throw e;
}
} Prevention
- This is primarily triggered by problematic/obfuscated bytecode; keep jadx updated.
- If developing jadx region visitors, ensure visit() returns true only on actual structural change, never unconditionally.
- Test visitors on obfuscated inputs to check convergence.
- Report inputs that trigger this with the visitor class name from the error message.
When it happens
Trigger: An IRegionIterativeVisitor's visit method returns true (repeat) on every pass without converging, exceeding the 5 * blockCount limit. This typically happens with visitors that make progress-detected-incorrect changes (oscillating between two states) or visitors that unconditionally return true.
Common situations: Decompiling heavily obfuscated bytecode, malformed DEX files, or code with pathological control flow (deeply nested loops, large switch statements, exception-heavy code) that causes a region visitor to fail to converge. Common with R8/ProGuard-obfuscated APKs. The error message identifies the specific visitor class and block count for diagnosis.
Related errors
- Arguments count limit reached: {}
- Bad name for type variable: {}
- Can't parse type: {}, unexpected: {}
- No inner type found: {}
- Unexpected inner type found: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/0f6b800f6d2f4efe.
Report an issue: GitHub.