{"record":{"id":"ff9548b88b3598ad","repo":"skylot/jadx","slug":"missing-class","errorCode":null,"errorMessage":"Missing class: ","messagePattern":"Missing class: ","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/clsp/ClsSet.java","lineNumber":113,"sourceCode":"\t\t\tArgType clsType = cls.getClassInfo().getType();\n\t\t\tString clsRawName = clsType.getObject();\n\t\t\tcls.load();\n\n\t\t\tClspClassSource source = getClspClassSource(cls);\n\t\t\tClspClass nClass = new ClspClass(clsType, k, cls.getAccessFlags().rawValue(), source);\n\t\t\tif (names.put(clsRawName, nClass) != null) {\n\t\t\t\tthrow new JadxRuntimeException(\"Duplicate class: \" + clsRawName);\n\t\t\t}\n\t\t\tk++;\n\t\t\tnClass.setTypeParameters(cls.getGenericTypeParameters());\n\t\t\tnClass.setMethods(getMethodsDetails(cls));\n\t\t}\n\t\tclasses = new ClspClass[k];\n\t\tk = 0;\n\t\tfor (ClassNode cls : list) {\n\t\t\tClspClass nClass = getCls(cls, names);\n\t\t\tif (nClass == null) {\n\t\t\t\tthrow new JadxRuntimeException(\"Missing class: \" + cls);\n\t\t\t}\n\t\t\tnClass.setParents(makeParentsArray(cls));\n\t\t\tclasses[k] = nClass;\n\t\t\tk++;\n\t\t}\n\t}\n\n\tprivate static ClspClassSource getClspClassSource(ClassNode cls) {\n\t\tString inputFileName = cls.getClsData().getInputFileName();\n\t\tint idx = inputFileName.indexOf(':');\n\t\tString sourceFile = inputFileName.substring(0, idx);\n\t\tClspClassSource source = ClspClassSource.getClspClassSource(sourceFile);\n\t\tif (source == ClspClassSource.APP) {\n\t\t\tthrow new JadxRuntimeException(\"Unexpected input file: \" + inputFileName);\n\t\t}\n\t\treturn source;\n\t}\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java#L95-L131","documentation":"Thrown by ClsSet.loadFrom when getCls(cls, names) returns null for a class that was just added to the names map. This is an internal consistency check: every ClassNode in the input list should be retrievable from the names map built in the first loop. A null return indicates the map lookup failed for a class that should be present, which would imply a hash/key inconsistency or concurrent modification.","triggerScenarios":"This error fires in the second loop of loadFrom where parents are assigned. getCls(cls, names) looks up by the class's raw name. A null return is theoretically impossible if the class was added in the first loop with the same key derivation, unless ArgType.getObject() returns a different value on the second call (mutable ArgType) or the map was concurrently modified.","commonSituations":"In practice, this is a defensive check that should never fire under normal operation. If it does, it indicates either a thread-safety issue (concurrent access to the RootNode during loadFrom), a bug in ArgType equality/hashing, or memory corruption. Extremely rare in production jadx usage.","solutions":["Ensure ClsSet.loadFrom is not called concurrently from multiple threads on the same RootNode.","Check for any custom modifications to ArgType that could make getObject() return inconsistent values across calls.","Report as a jadx internal bug with the class name and input that reproduces it — this is an invariant violation.","As a workaround, retry the operation on a freshly loaded RootNode to rule out transient state corruption."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    clsSet.loadFrom(root);\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().startsWith(\"Missing class:\")) {\n        LOG.error(\"Internal inconsistency: class lookup failed. This is likely a jadx bug.\", e);\n        // retry on a fresh RootNode\n    } else {\n        throw e;\n    }\n}","preventionTips":["Do not call ClsSet.loadFrom concurrently from multiple threads on the same RootNode.","Report this as a jadx internal bug if it occurs — it indicates an invariant violation.","Retry on a freshly loaded RootNode to rule out transient state corruption."],"tags":["classpath","clst","internal","class-processing"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}