{"record":{"id":"3858682bb38bc83b","repo":"NationalSecurityAgency/ghidra","slug":"could-not-instantiate-saveable-of-type","errorCode":null,"errorMessage":"Could not instantiate saveable of type ","messagePattern":"Could not instantiate saveable of type ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/map/AbstractDBTracePropertyMap.java","lineNumber":445,"sourceCode":"\t\t\tbyte[] enc = record.getBinaryData(column);\n\t\t\tif (enc == null) {\n\t\t\t\tsetValue(obj, null);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tSaveable value = getValue(obj);\n\t\t\t\tif (value == null) {\n\t\t\t\t\tvalue = obj.valueClass.getConstructor().newInstance();\n\t\t\t\t\tsetValue(obj, value);\n\t\t\t\t}\n\t\t\t\tObjectStorage objStorage = new ObjectStorageStreamAdapter(\n\t\t\t\t\tnew ObjectInputStream(new ByteArrayInputStream(enc)));\n\t\t\t\tvalue.restore(objStorage);\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tthrow new AssertionError(e);\n\t\t\t}\n\t\t\tcatch (InstantiationException | InvocationTargetException | SecurityException e) {\n\t\t\t\tthrow new RuntimeException(\n\t\t\t\t\t\"Could not instantiate saveable of type \" + obj.valueClass);\n\t\t\t}\n\t\t\tcatch (NoSuchMethodException e) {\n\t\t\t\tthrow new RuntimeException(\"Saveable must have a default constructor\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static class DBTraceStringPropertyMap\n\t\t\textends AbstractDBTracePropertyMap<String, DBTraceStringPropertyMapEntry> {\n\n\t\tpublic DBTraceStringPropertyMap(String name, DBHandle dbh, OpenMode openMode,\n\t\t\t\tReadWriteLock lock, TaskMonitor monitor, Language baseLanguage, DBTrace trace,\n\t\t\t\tDBTraceThreadManager threadManager) throws IOException, VersionException {\n\t\t\tsuper(name, dbh, openMode, lock, monitor, baseLanguage, trace, threadManager,\n\t\t\t\tDBTraceStringPropertyMapEntry.class, DBTraceStringPropertyMapEntry::new);\n\t\t}\n","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/map/AbstractDBTracePropertyMap.java#L427-L463","documentation":"Thrown by AbstractDBTracePropertyMap.doLoad() during deserialization of a Saveable property value from the trace database. It catches InstantiationException, InvocationTargetException, or SecurityException from the reflective call obj.valueClass.getConstructor().newInstance(), meaning the Saveable's value class could not be instantiated. This is a RuntimeException wrapping the original cause, indicating either a broken Saveable implementation, a constructor that throws, or a security manager restriction.","triggerScenarios":"Loading a trace database that contains property map entries whose Saveable value class fails reflective instantiation. This occurs when the valueClass's default constructor throws an exception, the class is abstract, or a SecurityManager blocks reflective access. The error is triggered during trace open/upgrade when doLoad reads binary data from the DB record.","commonSituations":"After upgrading Ghidra versions where a Saveable class's constructor signature or initialization logic changed and now throws. When a custom Saveable implementation has a buggy default constructor. When running under a restrictive SecurityManager that blocks reflection.","solutions":["Inspect the wrapped cause in the RuntimeException to identify the specific failure (InstantiationException = abstract class, InvocationTargetException = constructor threw, SecurityException = manager blocked access).","Fix the Saveable value class's default constructor so it completes without throwing.","If the Saveable class changed between versions, ensure a migration/upgrade path exists for old trace databases.","If the database is corrupt, restore from a backup or re-create the trace."],"exampleFix":"// before\npublic class MySaveable implements Saveable {\n    public MySaveable() {\n        // throws if someField not set\n        init(someField);\n    }\n}\n\n// after\npublic class MySaveable implements Saveable {\n    private Object someField = DEFAULT;\n    public MySaveable() {\n        // safe default, no exception\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Before opening a trace with Saveable properties, verify value classes\n// have accessible default constructors\nClass<?> valueClass = /* the registered Saveable class */;\ntry {\n    valueClass.getConstructor(); // check no-arg constructor exists\n    valueClass.getConstructor().newInstance(); // check it doesn't throw\n} catch (Exception e) {\n    // fix the class before opening the trace\n}","typeGuard":null,"tryCatchPattern":"try {\n    trace.open(programName, monitor);\n} catch (RuntimeException e) {\n    if (e.getCause() instanceof InstantiationException ||\n        e.getCause() instanceof InvocationTargetException ||\n        e.getCause() instanceof SecurityException) {\n        // Saveable value class failed to instantiate\n        // inspect e.getCause() for details\n    }\n}","preventionTips":["Ensure every Saveable class stored in property maps has a public no-arg constructor that does not throw.","Test Saveable instantiation in unit tests.","Handle Saveable class migrations when upgrading Ghidra versions."],"tags":["property-map","trace-database","serialization","reflection","unchecked-exception","corruption"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}