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

  1. Update jadx — block splitting logic is actively maintained
  2. Report the APK and the failing offset as a jadx issue
  3. Verify instruction boundaries with baksmali to confirm the offset is valid
  4. 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

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


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/f4aa9e20e45c6446. Report an issue: GitHub.