skylot/jadx · error · JadxRuntimeException

Failed to process method for inline

Error message

Failed to process method for inline: {}

What it means

Thrown by InlineMethods.processInvokeInsn() as a catch-all wrapper around the method-inlining pipeline. Any exception (not just JadxRuntimeException) thrown during MarkMethodsForInline.process(), forceProcess, or inlineMethod is caught and re-thrown with a descriptive message identifying the call method. This means the root cause is the wrapped exception, not this message itself.

Solutions

  1. Inspect the wrapped cause exception (JadxRuntimeException.getCause()) to identify the real failure.
  2. Upgrade jadx — inlining logic is regularly hardened.
  3. Disable method inlining via jadx args to avoid the visitor entirely.
  4. Catch JadxRuntimeException per class and skip; the method will remain as a call rather than inlined.

Example fix

// before
try {
    jadx.load();
    jadx.save();
} catch (JadxRuntimeException e) {
    // root cause lost / batch aborts
}

// after
try {
    jadx.load();
    jadx.save();
} catch (JadxRuntimeException e) {
    Throwable root = e.getCause() != null ? e.getCause() : e;
    LOG.error("Inline failed, cause: {}", root.getMessage(), root);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    javaClass.decompile();
} catch (JadxRuntimeException e) {
    Throwable cause = e.getCause() != null ? e.getCause() : e;
    LOG.warn("Method inline failed in {}: {}", javaClass.getName(), cause.getMessage(), cause);
}

Prevention

When it happens

Trigger: An InvokeNode is processed, the resolved call method is a MethodNode eligible for inlining, and during inlineMethod() or replaceRegs() an exception occurs — e.g. register replacement failure, instruction copy error, or an invariant violation in the inlined method's body. The catch block wraps it with the callMth identifier.

Common situations: Methods with complex control flow being inlined into callers — deep nesting, unusual register mappings, or interactions with other visitor passes. Common in heavily optimised or obfuscated code where method inlining exposes edge cases.

Related errors


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

Appendix: source

Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/InlineMethods.java:80

		try {
			MethodInlineAttr mia = MarkMethodsForInline.process(callMth);
			if (mia == null) {
				// method is not yet loaded => force process
				mth.addDebugComment("Class process forced to load method for inline: " + callMth);
				mth.root().getProcessClasses().forceProcess(callMth.getParentClass());
				// run check again
				mia = MarkMethodsForInline.process(callMth);
				if (mia == null) {
					mth.addWarnComment("Failed to check method for inline after forced process" + callMth);
					return;
				}
			}
			if (mia.notNeeded()) {
				return;
			}
			inlineMethod(mth, callMth, mia, block, insn);
		} catch (Exception e) {
			throw new JadxRuntimeException("Failed to process method for inline: " + callMth, e);
		}
	}

	private void inlineMethod(MethodNode mth, MethodNode callMth, MethodInlineAttr mia, BlockNode block, InvokeNode insn) {
		InsnNode inlCopy = mia.getInsn().copyWithoutResult();
		if (replaceRegs(mth, callMth, mia, insn, inlCopy)) {
			IMethodDetails methodDetailsAttr = inlCopy.get(AType.METHOD_DETAILS);
			// replaceInsn replaces the attributes as well, make sure to preserve METHOD_DETAILS
			if (BlockUtils.replaceInsn(mth, block, insn, inlCopy)) {
				if (methodDetailsAttr != null) {
					inlCopy.addAttr(methodDetailsAttr);
				}
				updateUsageInfo(mth, callMth, mia.getInsn());
				return;
			}
		}
		mth.addWarnComment("Failed to inline method: " + callMth);
		// undo changes to insn

View on GitHub (pinned to e738a26571)