skylot/jadx · error · JadxRuntimeException
Unexpected instance arg in invoke
Error message
Unexpected instance arg in invoke
What it means
Thrown by ConstInlineVisitor.addExplicitCast() when a constant being inlined lands in the instance-argument slot of an invoke instruction but the literal value is not zero. The code only handles the case where the instance arg is null (zero literal), inserting a cast; a non-zero literal as an instance arg is an unexpected state that would produce semantically wrong code, so jadx aborts.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlineVisitor.java:285
addExplicitCast(useInsn, litArg);
}
} else {
if (!useInsn.replaceArg(arg, constArg.duplicate())) {
return false;
}
}
useInsn.inheritMetadata(constInsn);
return true;
}
private static void addExplicitCast(InsnNode insn, LiteralArg arg) {
if (insn instanceof BaseInvokeNode) {
BaseInvokeNode callInsn = (BaseInvokeNode) insn;
MethodInfo callMth = callInsn.getCallMth();
if (callInsn.getInstanceArg() == arg) {
// instance arg is null, force cast
if (!arg.isZeroLiteral()) {
throw new JadxRuntimeException("Unexpected instance arg in invoke");
}
ArgType castType = callMth.getDeclClass().getType();
InsnNode castInsn = new IndexInsnNode(InsnType.CAST, castType, 1);
castInsn.addArg(arg);
castInsn.add(AFlag.EXPLICIT_CAST);
InsnArg wrapCast = InsnArg.wrapArg(castInsn);
wrapCast.setType(castType);
insn.replaceArg(arg, wrapCast);
} else {
int offset = callInsn.getFirstArgOffset();
int argIndex = insn.getArgIndex(arg);
ArgType argType = callMth.getArgumentsTypes().get(argIndex - offset);
if (argType.isPrimitive()) {
arg.setType(argType);
if (argType.equals(ArgType.BYTE)) {
arg.add(AFlag.EXPLICIT_PRIMITIVE_TYPE);
}
}View on GitHub (pinned to e738a26571)
Solutions
- Upgrade jadx — const-inlining logic is refined across releases.
- Disable const inlining via jadx args (set fallback options or use --no-debug-info / conservative mode) to avoid the visitor triggering.
- Catch JadxRuntimeException per class/method and skip.
- Report the issue with the instruction and call method info from the error context.
Example fix
// before — default settings trigger const inline visitor JadxArgs args = new JadxArgs(); args.setInputFiles(Arrays.asList(file)); // after — disable the visitor to avoid the crash args.setRunFinalDecompiler(false); // or disable specific visitors via args flags // Catch and skip the class as a safety net
Defensive patterns
Strategy: fallback
Try / catch
try {
javaClass.decompile();
} catch (JadxRuntimeException e) {
LOG.warn("Const-inline failure in {}: {}", javaClass.getName(), e.getMessage());
// Fall back: re-decompile with const inlining disabled
} Prevention
- Upgrade jadx — const-inlining heuristics improve regularly.
- If the error recurs on the same class, try disabling const inlining via JadxArgs or CLI flags.
- Isolate per-class failures with try-catch.
- Report the failing instruction context to the jadx project.
When it happens
Trigger: During const inlining, addExplicitCast() is called on a BaseInvokeNode. callInsn.getInstanceArg() == arg (the inlined const is the instance arg), but arg.isZeroLiteral() is false. This means a non-null constant was used where an object instance reference is expected — an inconsistent state from prior visitor passes.
Common situations: Complex bytecode where constant propagation interacts with invoke instructions in unusual ways, typically from heavily optimised or obfuscated code. Can also arise from bugs in earlier visitor passes that mis-type an argument.
Related errors
- Failed to process method for inline: {}
- Bad name for type variable: {}
- Can't parse type: {}, unexpected: {}
- No inner type found: {}
- Unexpected inner type found: {}
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/f4999f708766b87e.
Report an issue: GitHub.