skylot/jadx · error · JadxRuntimeException

Failed to generate 'invoke-custom' instruction:

Error message

Failed to generate 'invoke-custom' instruction: 

What it means

Thrown by InsnGen when generating an invoke-custom instruction (Java 8+ lambda/method reference) and any exception occurs during the process — building the call arguments, resolving the bootstrap method, or rendering the lambda body. The catch block wraps the original exception with this message. Invoke-custom is one of the most complex codegen paths due to the variety of bootstrap methods and lambda shapes.

Solutions

  1. Examine the cause exception for the specific failure point.
  2. Report the class and invoke-custom instruction to jadx with the full stack trace.
  3. Use fallback decompilation mode which may skip lambda reconstruction.
  4. Update jadx — invoke-custom handling is actively improved.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    codeGen.makeCode(cls);
} catch (JadxRuntimeException e) {
    if (e.getMessage().startsWith("Failed to generate 'invoke-custom'")) {
        Throwable cause = e.getCause();
        logger.error("invoke-custom codegen failed for {}: {}",
            cls.getClassInfo().getFullName(), cause.getMessage(), e);
        // Retry with fallback mode that skips lambda reconstruction
        args.setDecompilationMode(DecompilationMode.FALLBACK);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Processing an invoke-custom instruction where the call argument resolution or lambda body generation fails. Common with non-standard bootstrap methods, malformed LambdaMetafactory metafactory calls, or unusual method handle types. The inner cause exception has the specifics.

Common situations: Modern Java 8+ apps with complex lambda chains. Kotlin/Scala/Groovy compiled code using custom bootstrap methods. Obfuscated apps where invoke-custom metadata has been tampered with.

Related errors


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

Appendix: source

Thrown at jadx-core/src/main/java/jadx/core/codegen/InsnGen.java:1028

				}
				code.add(')');
			}
			code.add(" -> {");
			if (fallback) {
				code.add(" // ").add(implMthInfo.toString());
			}
			code.incIndent();
			code.startLine();
			if (!implMthInfo.getReturnType().isVoid()) {
				code.add("return ");
			}
			makeInsn(callInsn, code, Flags.INLINE);
			code.add(";");

			code.decIndent();
			code.startLine('}');
		} catch (Exception e) {
			throw new JadxRuntimeException("Failed to generate 'invoke-custom' instruction: " + e.getMessage(), e);
		}
	}

	private void makeInlinedLambdaMethod(ICodeWriter code, InvokeCustomNode customNode, MethodNode callMth) throws CodegenException {
		MethodGen callMthGen = new MethodGen(mgen.getClassGen(), callMth);
		NameGen nameGen = callMthGen.getNameGen();
		nameGen.inheritUsedNames(this.mgen.getNameGen());

		List<ArgType> implArgs = customNode.getImplMthInfo().getArgumentsTypes();
		List<RegisterArg> callArgs = callMth.getArgRegs();
		if (implArgs.isEmpty()) {
			code.add("()");
		} else {
			int callArgsCount = callArgs.size();
			int startArg = callArgsCount - implArgs.size();
			if (callArgsCount - startArg > 1) {
				code.add('(');
			}

View on GitHub (pinned to e738a26571)