NationalSecurityAgency/ghidra · error · TypeMismatchException

Property {} has type {}, which is not a super-type of {}

Error message

Property {} has type {}, which is not a super-type of {}

What it means

Thrown as TypeMismatchException by getPropertyMapSuper when the stored map's value class is not a supertype of the requested valueClass (i.e. stored class does NOT have the requested class as a subtype). This getter is for writing values contravariantly: you want a map that can accept the requested type.

Source

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

		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> TracePropertyMap<? super T> getOrCreatePropertyMapSuper(String name,
			Class<T> valueClass) {
		try (LockHold hold = LockHold.lock(lock.writeLock())) {
			AbstractDBTracePropertyMap<?, ?> map = propertyMapsByName.get(name);
			if (map == null) {
				try {
					return createPropertyMap(name, valueClass);
				}
				catch (DuplicateNameException e) {
					throw new AssertionError(e); // It cannot exist here
				}
			}
			if (!map.getValueClass().isAssignableFrom(valueClass)) {
				throw new TypeMismatchException("Property " + name + " has type " +
					map.getValueClass() + ", which is not a super-type of " + valueClass);
			}
			return (TracePropertyMap<? super T>) map;
		}
	}

	@Override
	public TracePropertyMap<?> getPropertyMap(String name) {
		try (LockHold hold = LockHold.lock(lock.readLock())) {
			return propertyMapsByName.get(name);
		}
	}

	@Override
	public Map<String, TracePropertyMap<?>> getAllProperties() {
		try (LockHold hold = LockHold.lock(lock.readLock())) {
			return Map.copyOf(propertyMapsByName);
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Query with a subtype of the stored class.
  2. If you need the covariant direction (querying with a supertype), use getPropertyMapExtends.
  3. Re-create the property map with a broader stored type if the contract changed.

Example fix

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

Strategy: validation

Validate before calling

AbstractDBTracePropertyMap<?,?> existing = mgr.getPropertyMap(name);
if (existing != null && !existing.getValueClass().isAssignableFrom(valueClass)) {
    // stored type is NOT a supertype of requested
}
return mgr.getPropertyMapSuper(name, valueClass);

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Map stored as Dog.class, queried via getPropertyMapSuper("x", Animal.class) — Dog is not a supertype of Animal, so it fails. The covariant reverse (querying with a subtype) succeeds.

Common situations: Choosing the wrong variance direction; refactoring that narrowed the stored type after the map was persisted.

Related errors


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