skylot/jadx · error · JadxRuntimeException
Constructor 'self' invoke must be removed!
Error message
Constructor 'self' invoke must be removed!
What it means
Thrown by InsnGen.makeConstructor() when a ConstructorInsn flagged as isSelf() (a this() call) reaches the code generator. Self constructor invokes should be eliminated during the earlier ConstructorInlineVisitor / modification passes, because Java does not allow explicit this() calls in decompiled output after constructor chain resolution. Their presence at codegen time indicates a bug in an earlier pass that failed to remove or transform the self-invoke.
Source
Thrown at jadx-core/src/main/java/jadx/core/codegen/InsnGen.java:734
code.add(", ");
}
wrap++;
if (wrap == 1000) {
code.startLine();
wrap = 0;
}
}
code.add('}');
}
private void makeConstructor(ConstructorInsn insn, ICodeWriter code) throws CodegenException {
ClassNode cls = mth.root().resolveClass(insn.getClassType());
if (cls != null && cls.isAnonymous() && !fallback) {
inlineAnonymousConstructor(code, cls, insn);
return;
}
if (insn.isSelf()) {
throw new JadxRuntimeException("Constructor 'self' invoke must be removed!");
}
MethodNode callMth = mth.root().resolveMethod(insn.getCallMth());
MethodNode refMth = callMth;
if (callMth != null) {
MethodReplaceAttr replaceAttr = callMth.get(AType.METHOD_REPLACE);
if (replaceAttr != null) {
refMth = replaceAttr.getReplaceMth();
}
}
if (insn.isSuper()) {
code.attachAnnotation(refMth);
code.add("super");
} else if (insn.isThis()) {
code.attachAnnotation(refMth);
code.add("this");
} else {
boolean forceShortName = addOuterClassInstance(insn, code, callMth);View on GitHub (pinned to e738a26571)
Solutions
- Report the class to the jadx project — the self-invoke should have been removed by an earlier pass.
- Update to the latest jadx version.
- Use fallback decompilation mode which may handle the constructor differently.
Defensive patterns
Strategy: try-catch
Try / catch
try {
// Class-level codegen
codeGen.makeCode(cls);
} catch (JadxRuntimeException e) {
if (e.getMessage().equals("Constructor 'self' invoke must be removed!")) {
logger.error("Self-invoke survived to codegen — internal jadx bug. " +
"Report the class: {}", cls.getClassInfo().getFullName(), e);
// Retry with fallback mode
args.setDecompilationMode(DecompilationMode.FALLBACK);
} else {
throw e;
}
} Prevention
- Report the class to jadx — the self-invoke should have been removed by ConstructorInlineVisitor.
- Use DecompilationMode.FALLBACK which bypasses the passes that should have removed it.
- Keep jadx updated — constructor processing is frequently improved.
When it happens
Trigger: A ConstructorInsn with isSelf()==true survives all processing passes and reaches makeConstructor(). This is a post-condition violation of the instruction processing pipeline.
Common situations: Complex constructor chains in obfuscated code that bypass the self-invoke removal pass. jadx version regressions in ConstructorInlineVisitor or related transforms. Kotlin/Scala compiled constructors with unusual patterns.
Related errors
- Method generation error
- Code generation error after restart
- Code generation error
- Error generate insn:
- Failed to generate 'invoke-custom' instruction:
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/b0e29fec7a767807.
Report an issue: GitHub.