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

  1. Check jadx logs for earlier ERROR/WARN messages about the same class — the real failure is upstream
  2. Update jadx — the save-vs-generate contract is periodically refined
  3. Report the class name and full log as a jadx issue since null code indicates a pipeline bug
  4. 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

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


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