{"record":{"id":"ac6e1830b3987a4c","repo":"skylot/jadx","slug":"input-class-not-found","errorCode":null,"errorMessage":"Input class not found: {}","messagePattern":"Input class not found: (.+?)","errorType":"validation","errorClass":"JadxArgsValidateException","httpStatus":null,"severity":"error","filePath":"jadx-cli/src/main/java/jadx/cli/SingleClassMode.java","lineNumber":37,"sourceCode":"public class SingleClassMode {\n\tprivate static final Logger LOG = LoggerFactory.getLogger(SingleClassMode.class);\n\n\tpublic static boolean process(JadxDecompiler jadx, JadxCLIArgs cliArgs) {\n\t\tString singleClass = cliArgs.getSingleClass();\n\t\tString singleClassOutput = cliArgs.getSingleClassOutput();\n\t\tif (singleClass == null && singleClassOutput == null) {\n\t\t\treturn false;\n\t\t}\n\t\tClassNode clsForProcess;\n\t\tif (singleClass != null) {\n\t\t\tclsForProcess = jadx.getRoot().resolveClass(singleClass);\n\t\t\tif (clsForProcess == null) {\n\t\t\t\tclsForProcess = jadx.getRoot().getClasses().stream()\n\t\t\t\t\t\t.filter(cls -> cls.getClassInfo().getAliasFullName().equals(singleClass))\n\t\t\t\t\t\t.findFirst().orElse(null);\n\t\t\t}\n\t\t\tif (clsForProcess == null) {\n\t\t\t\tthrow new JadxArgsValidateException(\"Input class not found: \" + singleClass);\n\t\t\t}\n\t\t\tif (clsForProcess.contains(AFlag.DONT_GENERATE)) {\n\t\t\t\tthrow new JadxArgsValidateException(\"Input class can't be saved by current jadx settings (marked as DONT_GENERATE)\");\n\t\t\t}\n\t\t\tif (clsForProcess.isInner()) {\n\t\t\t\tclsForProcess = clsForProcess.getTopParentClass();\n\t\t\t\tLOG.warn(\"Input class is inner, parent class will be saved: {}\", clsForProcess.getFullName());\n\t\t\t}\n\t\t} else {\n\t\t\t// singleClassOutput is set\n\t\t\t// expect only one class to be loaded\n\t\t\tList<ClassNode> classes = jadx.getRoot().getClasses().stream()\n\t\t\t\t\t.filter(c -> !c.isInner() && !c.contains(AFlag.DONT_GENERATE))\n\t\t\t\t\t.collect(Collectors.toList());\n\t\t\tint size = classes.size();\n\t\t\tif (size == 1) {\n\t\t\t\tclsForProcess = classes.get(0);\n\t\t\t} else {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-cli/src/main/java/jadx/cli/SingleClassMode.java#L19-L55","documentation":"Thrown by CodeAnnotationAdapter.read when deserializing a cached annotation: it reads a 1-byte tag and indexes adaptersByTag[tag]. Tags are assigned 1..N at construction time from the AnnType set the running jadx supports. A tag with no registered adapter (null slot) means the cache byte was written by a jadx build whose AnnType ordering/count differs, or the bytes are corrupt. It is a cache-format/version mismatch, not an application-logic error.","triggerScenarios":"Opening a cache produced by a different jadx version: the AnnType enum registered in registerAdapters() changed (added/removed/reordered), so a tag value written previously now indexes a null slot. Also possible if the cache file is truncated/corrupt so the byte read is garbage.","commonSituations":"Upgrading or downgrading jadx and reusing an old cache; opening a cache written by a fork with extra AnnTypes; filesystem corruption or a partial write leaving a stray tag byte; concurrent cache writes.","solutions":["Clear the jadx cache directory; the adapter table is rebuilt for the current version on next run.","Pin a single jadx version so cache format stays stable.","Upgrade jadx; newer builds treat an unknown tag as cache-invalidating rather than fatal.","Ensure no two jadx processes write the same cache concurrently."],"exampleFix":"// before\nTypeInfo typeInfo = adaptersByTag[tag];\nif (typeInfo == null) {\n    throw new RuntimeException(\"Unknown type tag: \" + tag);\n}\n\n// after\nTypeInfo typeInfo = (tag > 0 && tag < adaptersByTag.length) ? adaptersByTag[tag] : null;\nif (typeInfo == null) {\n    // version skew or corruption: discard this cache and recompute\n    throw new CacheInvalidatedException(\"Unknown type tag: \" + tag);\n}","handlingStrategy":"validation","validationCode":"// Validate the tag range/registration before indexing the adapter table:\nTypeInfo typeInfo = (tag > 0 && tag < adaptersByTag.length) ? adaptersByTag[tag] : null;\nif (typeInfo == null) {\n    // version skew or corruption: invalidate on-disk cache\n    invalidateCache();\n    return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n    return codeAnnotationAdapter.read(in);\n} catch (RuntimeException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unknown type tag\")) {\n        LOG.warn(\"Cache version mismatch, rebuilding: {}\", e.getMessage());\n        cacheDir.delete();\n        return null;\n    }\n    throw e;\n}","preventionTips":["Delete the cache after upgrading or downgrading jadx.","Run a single jadx version against a given cache directory.","Avoid concurrent writes to the same cache.","Let newer jadx invalidate on unknown tags instead of throwing."],"tags":["cache","disk-adapter","version-mismatch","annotation"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}