NationalSecurityAgency/ghidra · error · UnsupportedOperationException

Can only directly delete values for maps where the entry is

Error message

Can only directly delete values for maps where the entry is the value

What it means

Thrown by DBTraceAddressSnapRangePropertyMapSpace.deleteValue(T value) — the per-address-space variant of the same check as error 470. When the value is not an instance of AbstractDBTraceAddressSnapRangePropertyMapData, this space-level method throws UnsupportedOperationException (note: different exception type from the map-level IllegalArgumentException at 470, despite identical message). The space-level deleteValue can only operate when the entry is the value.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/map/DBTraceAddressSnapRangePropertyMapSpace.java:85

	@Override
	public Trace getTrace() {
		return trace;
	}

	@Override
	public AddressSpace getAddressSpace() {
		return space;
	}

	public <K> DBCachedObjectIndex<K, DR> getUserIndex(Class<K> fieldClass, DBObjectColumn column) {
		return tree.getUserIndex(fieldClass, column);
	}

	@Override
	@SuppressWarnings({ "unchecked" })
	public void deleteValue(T value) {
		if (!(value instanceof AbstractDBTraceAddressSnapRangePropertyMapData)) {
			throw new UnsupportedOperationException(
				"Can only directly delete values for maps where the entry is the value");
		}
		deleteData((DR) value);
	}

	public void deleteData(DR data) {
		if (data.tree != this.tree) {
			throw new IllegalArgumentException("The given entry is not in this space");
		}
		try (LockHold hold = LockHold.lock(lock.writeLock())) {
			tree.doDeleteEntry(data);
		}
	}

	@Override
	public T put(TraceAddressSnapRange shape, T value) {
		return map.put(shape, value);
	}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Use remove(TraceAddressSnapRange shape, T value) on the space instead of deleteValue() for non-entry values.
  2. Use deleteData(DR data) directly if you have the entry data object.
  3. Check value instanceof AbstractDBTraceAddressSnapRangePropertyMapData before calling deleteValue().

Example fix

// before
spaceMap.deleteValue(myValue);

// after
spaceMap.remove(shape, myValue);
// or if you have the entry:
if (myValue instanceof AbstractDBTraceAddressSnapRangePropertyMapData<?, ?> entry) {
    spaceMap.deleteData(entry);
}
Defensive patterns

Strategy: validation

Validate before calling

// Check before calling deleteValue on a space map
if (value instanceof AbstractDBTraceAddressSnapRangePropertyMapData) {
    spaceMap.deleteValue(value);
} else {
    spaceMap.remove(shape, value);
}

Type guard

// Type guard for safe space-level deleteValue
static <T> boolean isEntryValue(T value) {
    return value instanceof AbstractDBTraceAddressSnapRangePropertyMapData;
}

Prevention

When it happens

Trigger: Calling deleteValue(someValue) on a DBTraceAddressSnapRangePropertyMapSpace where someValue is not an AbstractDBTraceAddressSnapRangePropertyMapData. This happens when accessing a specific address space's property map directly and passing a raw value object.

Common situations: Directly accessing a space-level property map (via getForSpace) and attempting to delete a non-entry value. Generic map cleanup code operating at the space level without checking value types.

Related errors


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