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
- Re-fetch the instruction from its block immediately before calling isFirstInsn, instead of caching the InsnNode across transforms.
- Confirm the MethodNode argument is the one that actually owns the instruction.
- If writing a plugin/pass, null-check getBlockByInsn(mth, insn) before calling isFirstInsn.
- 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
- Do not cache InsnNode references across passes that may remove them.
- Re-resolve the insn's block with getBlockByInsn before calling isFirstInsn.
- Make sure the MethodNode passed in actually owns the instruction.
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
- Incorrect nodes count for selectOther: {} in {}
- Can't remove SSA var: {}, still in use, count: {}, list: {
- Live variable analysis reach iterations limit, blocks count:
- Usage info collection failed with error: {} at insn: {}
- Can't find block by offset: {} in list {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/16a0a5ba03fbfb0b.
Report an issue: GitHub.