NationalSecurityAgency/ghidra · error · UnsupportedOperationException

Set end-snap of root unit

Error message

Set end-snap of root unit

What it means

Thrown by AbstractDBTraceDataComponent.setEndSnap() because a data component inherits its lifespan from its root data unit — you cannot set the end snap on an individual component. The component's lifespan is a projection of the root unit's lifespan, so changing it independently is meaningless. To modify the lifespan, operate on the root unit's setEndSnap() instead.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/AbstractDBTraceDataComponent.java:127

	@Override
	public Language getLanguage() {
		return root.getLanguage();
	}

	@Override
	public Lifespan getLifespan() {
		return root.getLifespan();
	}

	@Override
	public long getStartSnap() {
		return root.getStartSnap();
	}

	@Override
	public void setEndSnap(long endSnap) {
		throw new UnsupportedOperationException("Set end-snap of root unit");
	}

	@Override
	public long getEndSnap() {
		return root.getEndSnap();
	}

	@Override
	public Address getAddress() {
		return address;
	}

	@Override
	public Address getMaxAddress() {
		return maxAddress;
	}

	@Override

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Operate on the root unit: component.getRoot().setEndSnap(endSnap).
  2. If you need component-level temporal control, restructure so each sub-value is its own independent data unit rather than a component of a composite.

Example fix

// before
for (var component : root.getDataComponents()) {
    component.setEndSnap(50); // throws
}

// after — set on the root
root.setEndSnap(50);
Defensive patterns

Strategy: validation

Validate before calling

// Never call setEndSnap on a component; route to the root
if (dataValue instanceof TraceDataComponent) {
    ((TraceDataComponent) dataValue).getRoot().setEndSnap(endSnap);
} else if (dataValue instanceof TraceData) {
    ((TraceData) dataValue).setEndSnap(endSnap);
}

Type guard

static boolean isModifiableLifespan(Object dataValue) {
    return dataValue instanceof TraceData && !(dataValue instanceof TraceDataComponent);
}

Try / catch

try {
    dataValue.setEndSnap(endSnap);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().contains("root unit")) {
        // Route to root
        ((TraceData) dataValue).getRoot().setEndSnap(endSnap);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling component.setEndSnap(n) on a data component object — any attempt to modify the temporal extent of a single sub-field within a composite data unit.

Common situations: Scripting that loops over data components and tries to adjust their lifespans; confusing component-level APIs with root-level APIs; generic code that treats all data values uniformly and calls setEndSnap.

Related errors


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