skylot/jadx · error · JadxRuntimeException
Code not generated for class {}
Error message
Code not generated for class {} What it means
Thrown when SaveCode.save() receives a null ICodeInfo for a class that was not marked DONT_GENERATE. A null result means the decompilation pipeline ran but never produced any code output for this class — indicating a silent upstream failure where a visitor exited without generating code and without throwing its own exception.
Source
Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java:29
import jadx.api.JadxArgs;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.FileUtils;
public class SaveCode {
private static final Logger LOG = LoggerFactory.getLogger(SaveCode.class);
private SaveCode() {
}
public static void save(File dir, ClassNode cls, ICodeInfo code) {
if (cls.contains(AFlag.DONT_GENERATE)) {
return;
}
if (code == null) {
throw new JadxRuntimeException("Code not generated for class " + cls.getFullName());
}
if (code == ICodeInfo.EMPTY) {
return;
}
String codeStr = code.getCodeStr();
if (codeStr.isEmpty()) {
return;
}
JadxArgs args = cls.root().getArgs();
if (args.isSkipFilesSave()) {
return;
}
String fileName = cls.getClassInfo().getAliasFullPath() + getFileExtension(cls.root());
if (!args.getSecurity().isValidEntryName(fileName)) {
return;
}
save(codeStr, new File(dir, fileName));
}View on GitHub (pinned to e738a26571)
Solutions
- Check jadx logs for earlier ERROR/WARN messages about the same class — the real failure is upstream
- Update jadx — the save-vs-generate contract is periodically refined
- Report the class name and full log as a jadx issue since null code indicates a pipeline bug
- As a workaround, run with --show-bad-code or exclude the class from output
Defensive patterns
Strategy: try-catch
Validate before calling
// Enable verbose logging before decompilation to capture upstream pipeline failures
JadxArgs args = new JadxArgs();
args.setOutputDir(outputDir);
args.setDebugInfo(true);
// Check for known problematic class patterns
for (ClassNode cls : rootNode.getClasses()) {
if (cls.contains(AFlag.DONT_GENERATE)) continue;
// Pre-check: log classes that may fail generation
LOG.debug("Will generate: {}", cls.getFullName());
} Try / catch
for (ClassNode cls : jadxDecompiler.getClasses()) {
try {
ICodeInfo code = jadxDecompiler.decompileClass(cls);
SaveCode.save(outputDir, cls, code);
} catch (JadxRuntimeException e) {
if (e.getMessage().contains("Code not generated")) {
LOG.error("Pipeline failed silently for class {}, check earlier logs", cls.getFullName(), e);
// Continue with other classes instead of failing the whole batch
} else {
throw e;
}
}
} Prevention
- Enable verbose/debug logging to catch upstream visitor failures before they reach SaveCode
- Use per-class decompilation loops so one class failure doesn't abort the entire batch
- Check jadx logs for ERROR entries about the same class before the SaveCode crash
- Update jadx — the code-generation contract is periodically refined
When it happens
Trigger: A ClassNode passes through the full visitor pipeline without being skipped, but the final code generation (ICodeInfo) returns null instead of ICodeInfo.EMPTY or a populated code info. This typically means a prior visitor consumed the class without generating output.
Common situations: A downstream visitor swallowed an exception or returned early without setting DONT_GENERATE; the class is synthetic or generated and its decompilation path is incomplete; version-specific pipeline ordering bugs where a new visitor changes the generation contract.
Related errors
- Decompilation batches build failed
- Failed to generate code for class: ${cls.getFullName()}
- Failed to process class: ${cls.getFullName()}
- Failed to process method to visitor:
- Unknown file format:
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/b330689324e26b0c.
Report an issue: GitHub.