skylot/jadx · error · JadxRuntimeException
Arg not found:
Error message
Arg not found:
What it means
Thrown by SkipMethodArgsAttr.skipArg(MethodNode, RegisterArg) when the given RegisterArg is not found by reference in the method's argument register list (Utils.indexInListByRef returns -1). It indicates the caller asked to skip a register that is not actually a declared argument of the method.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/attributes/nodes/SkipMethodArgsAttr.java:20
import java.util.BitSet;
import org.jetbrains.annotations.Nullable;
import jadx.api.plugins.input.data.attributes.PinnedAttribute;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
public class SkipMethodArgsAttr extends PinnedAttribute {
public static void skipArg(MethodNode mth, RegisterArg arg) {
int argNum = Utils.indexInListByRef(mth.getArgRegs(), arg);
if (argNum == -1) {
throw new JadxRuntimeException("Arg not found: " + arg);
}
skipArg(mth, argNum);
}
public static void skipArg(MethodNode mth, int argNum) {
SkipMethodArgsAttr attr = mth.get(AType.SKIP_MTH_ARGS);
if (attr == null) {
attr = new SkipMethodArgsAttr(mth);
mth.addAttr(attr);
}
attr.skip(argNum);
}
public static boolean isSkip(@Nullable MethodNode mth, int argNum) {
if (mth == null) {
return false;
}
if (argNum == 0 && mth.contains(AFlag.SKIP_FIRST_ARG)) {View on GitHub (pinned to e738a26571)
Solutions
- Before calling, confirm the arg is in mth.getArgRegs() by reference (Utils.indexInListByRef != -1).
- Use the integer-index overload skipArg(mth, argNum) once you have resolved the index yourself, with a guard for -1.
- Make sure the RegisterArg comes from the same MethodNode instance and is the original arg, not a renamed copy.
- If skipping should be best-effort, log and ignore a -1 result instead of throwing.
Example fix
// before
public static void skipArg(MethodNode mth, RegisterArg arg) {
int argNum = Utils.indexInListByRef(mth.getArgRegs(), arg);
if (argNum == -1) {
throw new JadxRuntimeException("Arg not found: " + arg);
}
skipArg(mth, argNum);
}
// after (guard at the call site)
int idx = Utils.indexInListByRef(mth.getArgRegs(), arg);
if (idx != -1) {
SkipMethodArgsAttr.skipArg(mth, idx);
} Defensive patterns
Strategy: validation
Validate before calling
int idx = Utils.indexInListByRef(mth.getArgRegs(), arg);
if (idx == -1) {
// arg is not a declared argument; do not skip
return;
}
SkipMethodArgsAttr.skipArg(mth, idx); Type guard
static boolean isMethodArg(MethodNode mth, RegisterArg arg) {
return Utils.indexInListByRef(mth.getArgRegs(), arg) != -1;
} Try / catch
try {
SkipMethodArgsAttr.skipArg(mth, arg);
} catch (JadxRuntimeException e) {
LOG.warn("Cannot skip arg {} in {}: not an argument register", arg, mth);
} Prevention
- Resolve the argument index yourself and guard for -1 before calling.
- Ensure the RegisterArg is from the same MethodNode and is the original arg register, not a copy.
- Prefer the integer-index overload skipArg(mth, int) once validated.
When it happens
Trigger: Passing a RegisterArg that is a copy, a this-pointer, or an intra-body temporary rather than a true argument register; calling skipArg with an arg belonging to a different MethodNode; calling after argument-register list has been rebuilt so the reference no longer matches.
Common situations: Plugins or post-processing passes that mark arguments to skip without checking membership; transformations that replace arg registers and leave stale references; bugs in caller code that confuses arg regs with locals.
Related errors
- Read limit exceeded
- Please specify input file
- File not found ${file.getAbsolutePath()}
- ${desc} directory exists as file ${dir}
- Unknown value '${val}' for option '${key}', expect: 'yes' or
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/9abd50e21a38882e.
Report an issue: GitHub.