{"record":{"id":"b1c9f79090501a32","repo":"NationalSecurityAgency/ghidra","slug":"unsupported-value-class","errorCode":null,"errorMessage":"Unsupported value class: {}","messagePattern":"Unsupported value class: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/property/DBTraceAddressPropertyManager.java","lineNumber":167,"sourceCode":"\t\t\t}\n\t\t\tif (valueClass == Void.class) {\n\t\t\t\treturn (AbstractDBTracePropertyMap<T, ?>) new DBTraceVoidPropertyMap(tableName, dbh,\n\t\t\t\t\topenMode, lock, TaskMonitor.DUMMY, baseLanguage, trace, threadManager);\n\t\t\t}\n\t\t\tif (Saveable.class.isAssignableFrom(valueClass)) {\n\t\t\t\tClass<? extends Saveable> saveableClass = valueClass.asSubclass(Saveable.class);\n\t\t\t\treturn (AbstractDBTracePropertyMap<T, ?>) new DBTraceSaveablePropertyMap<>(\n\t\t\t\t\ttableName, dbh, openMode, lock, TaskMonitor.DUMMY, baseLanguage, trace,\n\t\t\t\t\tthreadManager, saveableClass);\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tdbError(e);\n\t\t}\n\t\tcatch (VersionException e) {\n\t\t\tthrow new AssertionError(e);\n\t\t}\n\t\tthrow new IllegalArgumentException(\"Unsupported value class: \" + valueClass);\n\t}\n\n\t@Override\n\tpublic <T> AbstractDBTracePropertyMap<T, ?> createPropertyMap(String name, Class<T> valueClass)\n\t\t\tthrows DuplicateNameException {\n\t\ttry (LockHold hold = LockHold.lock(lock.writeLock())) {\n\t\t\tif (propertyMapsByName.containsKey(name)) {\n\t\t\t\tthrow new DuplicateNameException(name);\n\t\t\t}\n\t\t\tDBTraceAddressPropertyEntry ent = propertyStore.create();\n\t\t\tent.set(name, valueClass);\n\t\t\tAbstractDBTracePropertyMap<T, ?> map = doCreateMap(name, OpenMode.CREATE, valueClass);\n\t\t\tent.map = map;\n\t\t\tpropertyMapsByName.put(name, map);\n\t\t\treturn map;\n\t\t}\n\t}\n","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/property/DBTraceAddressPropertyManager.java#L149-L185","documentation":"Thrown by DBTraceAddressPropertyManager.doCreateMap when the requested property value class is none of the supported types. Supported classes are exactly Integer, Long, String, Void, or any subclass of ghidra.framework.save.Saveable. Any other Class<T> (e.g. Double, Boolean, Address, a plain POJO) reaches the terminal throw. This is a programming contract violation rather than a runtime data problem.","triggerScenarios":"Calling createPropertyMap(name, Double.class), createPropertyMap(name, Address.class), or getOrCreatePropertyMap with an arbitrary custom class that is not a Saveable subclass.","commonSituations":"Developer assumes arbitrary value types are allowed and passes Boolean/Double/byte[]. Passing a Saveable subclass that fails the isAssignableFrom check due to a raw/generic Class token erasure.","solutions":["Use one of the built-in classes: Integer, Long, String, or Void.","For complex types, implement a class extending ghidra.framework.save.Saveable and pass its Class.","If you need a boolean, store it as a Void presence marker or wrap in a Saveable."],"exampleFix":"// before\npropMgr.createPropertyMap(\"flag\", Boolean.class);\n// after\npropMgr.createPropertyMap(\"flag\", Integer.class); // store 0/1\n// or implement BooleanSaveable extends Saveable","handlingStrategy":"type-guard","validationCode":"boolean supported = valueClass == Integer.class || valueClass == Long.class ||\n    valueClass == String.class || valueClass == Void.class ||\n    Saveable.class.isAssignableFrom(valueClass);\nif (!supported) throw new IllegalArgumentException(\"unsupported\");\nmgr.createPropertyMap(name, valueClass);","typeGuard":"static boolean isSupportedValueClass(Class<?> c) {\n    return c == Integer.class || c == Long.class || c == String.class\n        || c == Void.class || Saveable.class.isAssignableFrom(c);\n}","tryCatchPattern":null,"preventionTips":["Restrict property value types to Integer, Long, String, Void, or a Saveable subclass.","Wrap non-conforming types in a custom Saveable."],"tags":["property-map","saveable","validation","api-contract"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}