NationalSecurityAgency/ghidra · error · TypeMismatchException
Property {} has type {}, not {}
Error message
Property {} has type {}, not {} What it means
Thrown as TypeMismatchException by getPropertyMap(name, valueClass) when a map exists under name but its stored value class is not exactly equal to the requested valueClass. Equality is by reference identity (==) on the Class objects, so even a compatible subtype will fail this strict variant. Use getPropertyMapExtends for subtype-tolerant lookup.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/property/DBTraceAddressPropertyManager.java:195
DBTraceAddressPropertyEntry ent = propertyStore.create();
ent.set(name, valueClass);
AbstractDBTracePropertyMap<T, ?> map = doCreateMap(name, OpenMode.CREATE, valueClass);
ent.map = map;
propertyMapsByName.put(name, map);
return map;
}
}
@Override
@SuppressWarnings("unchecked")
public <T> AbstractDBTracePropertyMap<T, ?> getPropertyMap(String name, Class<T> valueClass) {
try (LockHold hold = LockHold.lock(lock.readLock())) {
AbstractDBTracePropertyMap<?, ?> map = propertyMapsByName.get(name);
if (map == null) {
return null;
}
if (valueClass != map.getValueClass()) {
throw new TypeMismatchException("Property " + name + " has type " +
map.getValueClass() + ", not " + valueClass);
}
return (AbstractDBTracePropertyMap<T, ?>) map;
}
}
@Override
@SuppressWarnings("unchecked")
public <T> TracePropertyMap<? extends T> getPropertyMapExtends(String name,
Class<T> valueClass) {
try (LockHold hold = LockHold.lock(lock.readLock())) {
AbstractDBTracePropertyMap<?, ?> map = propertyMapsByName.get(name);
if (map == null) {
return null;
}
if (!valueClass.isAssignableFrom(map.getValueClass())) {
throw new TypeMismatchException("Property " + name + " has type " +
map.getValueClass() + ", which does not extend " + valueClass);View on GitHub (pinned to d5f144c24d)
Solutions
- Query with the exact class the map was created with (check via getPropertyMap(name).getValueClass()).
- If you only need a supertype view, call getPropertyMapExtends(name, supertype.class).
- If you only need a subtype view, call getPropertyMapSuper (the inverse-tolerant getter).
Example fix
// before
TracePropertyMap<String> m = mgr.getPropertyMap("note", Object.class);
// after
TracePropertyMap<? extends Object> m =
mgr.getPropertyMapExtends("note", Object.class); Defensive patterns
Strategy: validation
Validate before calling
AbstractDBTracePropertyMap<?,?> existing = mgr.getPropertyMap(name);
if (existing == null) return null;
if (existing.getValueClass() != valueClass) {
// decide: use extends/super getter or fail
}
return mgr.getPropertyMap(name, valueClass); Type guard
static boolean sameValueClass(AbstractDBTracePropertyMap<?,?> m, Class<?> c) {
return m.getValueClass() == c;
} Try / catch
try { return mgr.getPropertyMap(name, cls); }
catch (TypeMismatchException e) { /* inspect getValueClass */ } Prevention
- Query with the exact stored class; inspect getValueClass() first.
- Use the extends/super getters when you need variance.
When it happens
Trigger: A map was created as String.class but queried with getPropertyMap("note", Object.class), or created as a Saveable subclass and queried with the parent Saveable class.
Common situations: Two modules share a property name but disagree on the declared value type; refactoring changed a value class while a persisted trace stores the old class.
Related errors
- Property {} has type {}, which does not extend {}
- Property {} has type {}, which is not a super-type of {}
- Can only directly delete values for maps where the entry is
- Can only directly delete values for maps where the entry is
- Property ${propertyName} is not object type
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/484de67e6d844457.
Report an issue: GitHub.