{"record":{"id":"b330689324e26b0c","repo":"skylot/jadx","slug":"code-not-generated-for-class","errorCode":null,"errorMessage":"Code not generated for class {}","messagePattern":"Code not generated for class (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java","lineNumber":29,"sourceCode":"import jadx.api.JadxArgs;\nimport jadx.core.dex.attributes.AFlag;\nimport jadx.core.dex.nodes.ClassNode;\nimport jadx.core.dex.nodes.RootNode;\nimport jadx.core.utils.exceptions.JadxRuntimeException;\nimport jadx.core.utils.files.FileUtils;\n\npublic class SaveCode {\n\tprivate static final Logger LOG = LoggerFactory.getLogger(SaveCode.class);\n\n\tprivate SaveCode() {\n\t}\n\n\tpublic static void save(File dir, ClassNode cls, ICodeInfo code) {\n\t\tif (cls.contains(AFlag.DONT_GENERATE)) {\n\t\t\treturn;\n\t\t}\n\t\tif (code == null) {\n\t\t\tthrow new JadxRuntimeException(\"Code not generated for class \" + cls.getFullName());\n\t\t}\n\t\tif (code == ICodeInfo.EMPTY) {\n\t\t\treturn;\n\t\t}\n\t\tString codeStr = code.getCodeStr();\n\t\tif (codeStr.isEmpty()) {\n\t\t\treturn;\n\t\t}\n\t\tJadxArgs args = cls.root().getArgs();\n\t\tif (args.isSkipFilesSave()) {\n\t\t\treturn;\n\t\t}\n\t\tString fileName = cls.getClassInfo().getAliasFullPath() + getFileExtension(cls.root());\n\t\tif (!args.getSecurity().isValidEntryName(fileName)) {\n\t\t\treturn;\n\t\t}\n\t\tsave(codeStr, new File(dir, fileName));\n\t}","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java#L11-L47","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Enable verbose logging before decompilation to capture upstream pipeline failures\nJadxArgs args = new JadxArgs();\nargs.setOutputDir(outputDir);\nargs.setDebugInfo(true);\n// Check for known problematic class patterns\nfor (ClassNode cls : rootNode.getClasses()) {\n    if (cls.contains(AFlag.DONT_GENERATE)) continue;\n    // Pre-check: log classes that may fail generation\n    LOG.debug(\"Will generate: {}\", cls.getFullName());\n}","typeGuard":null,"tryCatchPattern":"for (ClassNode cls : jadxDecompiler.getClasses()) {\n    try {\n        ICodeInfo code = jadxDecompiler.decompileClass(cls);\n        SaveCode.save(outputDir, cls, code);\n    } catch (JadxRuntimeException e) {\n        if (e.getMessage().contains(\"Code not generated\")) {\n            LOG.error(\"Pipeline failed silently for class {}, check earlier logs\", cls.getFullName(), e);\n            // Continue with other classes instead of failing the whole batch\n        } else {\n            throw e;\n        }\n    }\n}","preventionTips":["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"],"tags":["code-generation","save","pipeline","decompiler"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}