skylot/jadx · error · JadxOverflowException
Regions count limit reached at block {}
Error message
Regions count limit reached at block {} What it means
Thrown by RegionMaker.makeRegion when the block-traversal loop produces more than regionsLimit (basicBlocks.size() * 400) regions for a single method. It guards region construction against pathological control-flow explosion that would otherwise exhaust memory or run for minutes. A JadxOverflowException, so it is meant to be catchable and to fail one method, not the whole run.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/regions/maker/RegionMaker.java:72
Region region = new Region(stack.peekRegion());
if (stack.containsExit(startBlock)) {
insertEdgeInsns(region, startBlock);
return region;
}
if (processedBlocks.addChecked(startBlock)) {
// Add block to multiple regions (duplicate the instructions in decompiled code)
// and allow processing to continue
if (!startBlock.contains(AFlag.DUPLICATED)) {
mth.addWarnComment("Code duplicated, block: " + startBlock + ' ' + startBlock.getAttributesString());
startBlock.add(AFlag.DUPLICATED);
}
}
BlockNode next = startBlock;
while (next != null) {
next = traverse(region, next);
regionsCount++;
if (regionsCount > regionsLimit) {
throw new JadxOverflowException("Regions count limit reached at block " + startBlock);
}
}
return region;
}
/**
* Recursively traverse all blocks from 'block' until block from 'exits'
*/
private @Nullable BlockNode traverse(Region r, BlockNode block) {
if (block.contains(AFlag.MTH_EXIT_BLOCK)) {
return null;
}
BlockNode next = null;
boolean processed = false;
List<LoopInfo> loops = block.getAll(AType.LOOP);
int loopCount = loops.size();
if (loopCount != 0 && block.contains(AFlag.LOOP_START)) {View on GitHub (pinned to e738a26571)
Solutions
- Update jadx; the multiplier and traversal have been tuned repeatedly.
- Report the input with the method name so the region-maker logic can be improved.
- Decompile the class with the method excluded, or run with the CLI/GUI 'skip errors' style flow that records the failure as a method warning instead of aborting.
- If embedding jadx, catch JadxOverflowException per class/method.
Example fix
// before
ClassNode cls = ...;
new RegionMaker(cls).makeMthRegion();
// after
try {
new RegionMaker(cls).makeMthRegion();
} catch (JadxOverflowException e) {
cls.addError("region build overflow", e);
} Defensive patterns
Strategy: try-catch
Try / catch
try {
cls.decompile();
} catch (JadxOverflowException e) {
cls.addError("region count overflow", e);
} Prevention
- Treat JadxOverflowException as 'skip this method, keep going'.
- Surface method-level errors to the user instead of aborting a batch run.
- Report inputs that trigger this so the 400x multiplier or traversal can be revisited.
When it happens
Trigger: Decompiling a method whose CFG, after block merging, causes traverse() to keep returning non-null next blocks and accumulate regions beyond 400 * basicBlocks.size(). Typical of generated state-machine code, huge switch ladders, or methods flattened by obfuscators.
Common situations: Obfuscated apps, methods decompiled from native-to-DEX translators, auto-generated lookup tables encoded as switch/if chains, or methods with many duplicated blocks (the DUPLICATED path above this check is what usually precedes the blow-up).
Related errors
- Regions stack size limit reached
- Duplicate predecessors in PHI insn: {}, {}
- Bad name for type variable: {}
- Can't parse type: {}, unexpected: {}
- No inner type found: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/5048af5bd1c0fab3.
Report an issue: GitHub.