skylot/jadx · error · JadxRuntimeException

Insn not found in method: {}

Error message

Insn not found in method: {}

What it means

Thrown by BlockUtils.isFirstInsn when getBlockByInsn(mth, insn) returns null - i.e. the instruction is not present in any basic block of the method. isFirstInsn walks the enter block, then (if that is empty) looks up the instruction's block; if no block contains it, the lookup fails. It indicates the instruction was already removed, belongs to a different method, or is a synthetic with no placement.

Source

Thrown at jadx-core/src/main/java/jadx/core/utils/BlockUtils.java:1381

				return null;
			}
			if (insn != null) {
				return null;
			}
			insn = blockInsns.get(0);
		}
		return insn;
	}

	public static boolean isFirstInsn(MethodNode mth, InsnNode insn) {
		BlockNode startBlock = followEmptyPath(mth.getEnterBlock());
		if (startBlock != null && !startBlock.getInstructions().isEmpty()) {
			return startBlock.getInstructions().get(0) == insn;
		}
		// handle branching with empty blocks
		BlockNode block = getBlockByInsn(mth, insn);
		if (block == null) {
			throw new JadxRuntimeException("Insn not found in method: " + insn);
		}
		if (block.getInstructions().get(0) != insn) {
			return false;
		}
		Set<BlockNode> allPathsBlocks = getAllPathsBlocks(mth.getEnterBlock(), block);
		for (BlockNode pathBlock : allPathsBlocks) {
			if (!pathBlock.getInstructions().isEmpty() && pathBlock != block) {
				return false;
			}
		}
		return true;
	}

	/**
	 * Replace insn by index i in block,
	 * for proper copy attributes, assume attributes are not overlap
	 */
	public static void replaceInsn(MethodNode mth, BlockNode block, int i, InsnNode insn) {

View on GitHub (pinned to e738a26571)

Solutions

  1. Re-fetch the instruction from its block immediately before calling isFirstInsn, instead of caching the InsnNode across transforms.
  2. Confirm the MethodNode argument is the one that actually owns the instruction.
  3. If writing a plugin/pass, null-check getBlockByInsn(mth, insn) before calling isFirstInsn.
  4. Update jadx and report the method if this fires from jadx's own passes.

Example fix

// before
if (BlockUtils.isFirstInsn(mth, maybeStaleInsn)) { ... }
// after - re-resolve from the current block graph
BlockNode b = BlockUtils.getBlockByInsn(mth, maybeStaleInsn);
if (b != null && BlockUtils.isFirstInsn(mth, maybeStaleInsn)) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// confirm the insn still lives in the method before asking about it
BlockNode b = BlockUtils.getBlockByInsn(mth, insn);
if (b == null) {
    // insn is not in mth - skip the isFirstInsn check
    return false;
}
boolean first = BlockUtils.isFirstInsn(mth, insn);

Try / catch

try {
    return BlockUtils.isFirstInsn(mth, insn);
} catch (JadxRuntimeException e) {
    return false; // insn no longer in mth
}

Prevention

When it happens

Trigger: Calling isFirstInsn(mth, insn) with an InsnNode that is not in mth's basic blocks: an instruction removed by an earlier pass, an instruction constructed in a plugin but not inserted, or an instruction from a different MethodNode. The error names the offending instruction.

Common situations: Plugin/pass code that holds a stale InsnNode reference after a transform, or passes the wrong MethodNode. In jadx internals it can appear as a secondary effect of a pass that removed an instruction but did not invalidate callers holding the reference.

Related errors


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