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.
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)
Solutions
- Examine the cause exception for the specific failure point.
- Report the class and invoke-custom instruction to jadx with the full stack trace.
- Use fallback decompilation mode which may skip lambda reconstruction.
- 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
- Examine the cause exception for the specific invoke-custom failure.
- Use fallback mode for apps with complex or non-standard lambda/bootstrap patterns.
- Update jadx — invoke-custom handling is actively improved in each release.
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
- Unexpected argument type in lambda call:
- Unexpected field type class:
- Can't decode value:
- Method generation error
- Code generation error after restart
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/8e37ff4dc9608cd6.
Report an issue: GitHub.