{"record":{"id":"18e639ec80a88900","repo":"NationalSecurityAgency/ghidra","slug":"property-has-type-which-does-not-extend","errorCode":null,"errorMessage":"Property {} has type {}, which does not extend {}","messagePattern":"Property (.+?) has type (.+?), which does not extend (.+?)","errorType":"validation","errorClass":"TypeMismatchException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/property/DBTraceAddressPropertyManager.java","lineNumber":212,"sourceCode":"\t\t\tif (valueClass != map.getValueClass()) {\n\t\t\t\tthrow new TypeMismatchException(\"Property \" + name + \" has type \" +\n\t\t\t\t\tmap.getValueClass() + \", not \" + valueClass);\n\t\t\t}\n\t\t\treturn (AbstractDBTracePropertyMap<T, ?>) map;\n\t\t}\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\tpublic <T> TracePropertyMap<? extends T> getPropertyMapExtends(String name,\n\t\t\tClass<T> valueClass) {\n\t\ttry (LockHold hold = LockHold.lock(lock.readLock())) {\n\t\t\tAbstractDBTracePropertyMap<?, ?> map = propertyMapsByName.get(name);\n\t\t\tif (map == null) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!valueClass.isAssignableFrom(map.getValueClass())) {\n\t\t\t\tthrow new TypeMismatchException(\"Property \" + name + \" has type \" +\n\t\t\t\t\tmap.getValueClass() + \", which does not extend \" + valueClass);\n\t\t\t}\n\t\t\treturn (TracePropertyMap<? extends T>) map;\n\t\t}\n\t}\n\n\t@Override\n\tpublic <T> AbstractDBTracePropertyMap<T, ?> getOrCreatePropertyMap(String name,\n\t\t\tClass<T> valueClass) {\n\t\ttry (LockHold hold = LockHold.lock(lock.writeLock())) {\n\t\t\tAbstractDBTracePropertyMap<T, ?> map = getPropertyMap(name, valueClass);\n\t\t\tif (map != null) {\n\t\t\t\treturn map;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn createPropertyMap(name, valueClass);\n\t\t\t}\n\t\t\tcatch (DuplicateNameException e) {","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/property/DBTraceAddressPropertyManager.java#L194-L230","documentation":"Thrown as TypeMismatchException by getPropertyMapExtends when the stored map's value class is NOT assignable to the requested valueClass (i.e. the stored type does not extend/is not the requested type). This getter is meant for reading values covariantly: you want a view whose values are at least of the requested type.","triggerScenarios":"Map stored as Animal.class, queried via getPropertyMapExtends(\"x\", Dog.class) — Animal does not extend Dog, so it fails. The reverse direction (querying a supertype) succeeds.","commonSituations":"Confusing the extends vs super direction when choosing among getPropertyMap / getPropertyMapExtends / getPropertyMapSuper.","solutions":["Query with a supertype of the stored class, not a subtype.","If you need the inverse (querying with a subtype of the stored class), use getPropertyMapSuper.","Inspect map.getValueClass() first to pick the correct getter."],"exampleFix":"// before\nTracePropertyMap<? extends Dog> m =\n    mgr.getPropertyMapExtends(\"x\", Dog.class); // stored Animal\n// after\nTracePropertyMap<? extends Animal> m =\n    mgr.getPropertyMapExtends(\"x\", Animal.class);","handlingStrategy":"validation","validationCode":"AbstractDBTracePropertyMap<?,?> existing = mgr.getPropertyMap(name);\nif (existing != null && !valueClass.isAssignableFrom(existing.getValueClass())) {\n    // stored type does NOT extend requested; choose another getter\n}\nreturn mgr.getPropertyMapExtends(name, valueClass);","typeGuard":"static boolean storedExtends(Class<?> requested, Class<?> stored) {\n    return requested.isAssignableFrom(stored);\n}","tryCatchPattern":"try { return mgr.getPropertyMapExtends(name, cls); }\ncatch (TypeMismatchException e) { /* use getPropertyMapSuper or exact */ }","preventionTips":["Remember getPropertyMapExtends is covariant: request a supertype.","Use getPropertyMapSuper for the contravariant direction."],"tags":["property-map","type-mismatch","generics"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}