NationalSecurityAgency/ghidra · error · TypeMismatchException

Property {} has type {}, which does not extend {}

Error message

Property {} has type {}, which does not extend {}

What it means

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.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/property/DBTraceAddressPropertyManager.java:212

			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);
			}
			return (TracePropertyMap<? extends T>) map;
		}
	}

	@Override
	public <T> AbstractDBTracePropertyMap<T, ?> getOrCreatePropertyMap(String name,
			Class<T> valueClass) {
		try (LockHold hold = LockHold.lock(lock.writeLock())) {
			AbstractDBTracePropertyMap<T, ?> map = getPropertyMap(name, valueClass);
			if (map != null) {
				return map;
			}
			try {
				return createPropertyMap(name, valueClass);
			}
			catch (DuplicateNameException e) {

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Query with a supertype of the stored class, not a subtype.
  2. If you need the inverse (querying with a subtype of the stored class), use getPropertyMapSuper.
  3. Inspect map.getValueClass() first to pick the correct getter.

Example fix

// before
TracePropertyMap<? extends Dog> m =
    mgr.getPropertyMapExtends("x", Dog.class); // stored Animal
// after
TracePropertyMap<? extends Animal> m =
    mgr.getPropertyMapExtends("x", Animal.class);
Defensive patterns

Strategy: validation

Validate before calling

AbstractDBTracePropertyMap<?,?> existing = mgr.getPropertyMap(name);
if (existing != null && !valueClass.isAssignableFrom(existing.getValueClass())) {
    // stored type does NOT extend requested; choose another getter
}
return mgr.getPropertyMapExtends(name, valueClass);

Type guard

static boolean storedExtends(Class<?> requested, Class<?> stored) {
    return requested.isAssignableFrom(stored);
}

Try / catch

try { return mgr.getPropertyMapExtends(name, cls); }
catch (TypeMismatchException e) { /* use getPropertyMapSuper or exact */ }

Prevention

When it happens

Trigger: 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.

Common situations: Confusing the extends vs super direction when choosing among getPropertyMap / getPropertyMapExtends / getPropertyMapSuper.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/18e639ec80a88900. Report an issue: GitHub.