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

  1. Before calling, confirm the arg is in mth.getArgRegs() by reference (Utils.indexInListByRef != -1).
  2. Use the integer-index overload skipArg(mth, argNum) once you have resolved the index yourself, with a guard for -1.
  3. Make sure the RegisterArg comes from the same MethodNode instance and is the original arg, not a renamed copy.
  4. 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

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


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