skylot/jadx · error · JadxRuntimeException
Missing block: {}
Error message
Missing block: {} What it means
Thrown by the getBlock helper when looking up a block by code offset in the blocksMap. Every jump target, switch case, and exception handler offset must correspond to a block start. If an offset has no entry in the map, block splitting failed to create a block boundary at that offset.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockSplitter.java:334
}
}
return false;
}
private static boolean isDoWhile(Map<Integer, BlockNode> blocksMap, BlockNode curBlock, InsnNode insn) {
// split 'do-while' block (last instruction: 'if', target this block)
if (insn.getType() != InsnType.IF) {
return false;
}
IfNode ifs = (IfNode) insn;
BlockNode targetBlock = blocksMap.get(ifs.getTarget());
return targetBlock == curBlock;
}
private static BlockNode getBlock(int offset, Map<Integer, BlockNode> blocksMap) {
BlockNode block = blocksMap.get(offset);
if (block == null) {
throw new JadxRuntimeException("Missing block: " + offset);
}
return block;
}
private static void expandMoveMulti(MethodNode mth) {
for (BlockNode block : mth.getBasicBlocks()) {
List<InsnNode> insnsList = block.getInstructions();
int len = insnsList.size();
for (int i = 0; i < len; i++) {
InsnNode insn = insnsList.get(i);
if (insn.getType() == InsnType.MOVE_MULTI) {
int mvCount = insn.getArgsCount() / 2;
for (int j = 0; j < mvCount; j++) {
InsnNode mv = new InsnNode(InsnType.MOVE, 1);
int startArg = j * 2;
mv.setResult((RegisterArg) insn.getArg(startArg));
mv.addArg(insn.getArg(startArg + 1));
mv.copyAttributesFrom(insn);View on GitHub (pinned to e738a26571)
Solutions
- Update jadx — block splitting logic is actively maintained
- Report the APK and the failing offset as a jadx issue
- Verify instruction boundaries with baksmali to confirm the offset is valid
- Try decompiling with --fallback mode for raw output on the problem class
Defensive patterns
Strategy: try-catch
Try / catch
try {
jadxDecompiler.load();
jadxDecompiler.save();
} catch (JadxRuntimeException e) {
if (e.getMessage().contains("Missing block")) {
LOG.warn("Block offset resolution failure, trying fallback mode");
args.setFallbackMode(true);
jadxDecompiler = new JadxDecompiler(args);
jadxDecompiler.load();
jadxDecompiler.save();
} else {
throw e;
}
} Prevention
- Verify instruction boundaries with baksmali/dexdump before decompiling
- Keep jadx updated — block splitting is actively maintained
- Try --fallback mode for raw output on problematic classes
- Report the APK as a jadx issue with the failing offset
When it happens
Trigger: A code offset (jump target, handler offset, or data target) passed to getBlock has no corresponding BlockNode in blocksMap. The block splitter did not register a block at that instruction boundary.
Common situations: Misaligned instruction boundaries from obfuscation; DEX files with unusual instruction alignments; bugs in the block splitting pass where a target offset falls in the middle of an instruction or at an unsplit boundary.
Related errors
- Unexpected missing predecessor for block: {}
- Failed to find top block for try-catch from: {}
- Unreachable block: {}
- Copy blocks tree failed. Missing block for connection: {}
- Found unreachable blocks
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/f4aa9e20e45c6446.
Report an issue: GitHub.