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;
}
@OverrideView on GitHub (pinned to d5f144c24d)
Solutions
- Operate on the root unit: component.getRoot().setEndSnap(endSnap).
- 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
- Always call setEndSnap on the root data unit, never on a component.
- Type-check for TraceDataComponent before calling lifespan-modifying methods.
- Design generic handlers to detect component vs. root and delegate appropriately.
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
- Code units cannot overlap
- Either delete the root, or modify the type
- endpoint cannot be -1
- Another mapping would conflict
- Given bookmark is not present at this view's snap
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/73a5a3147f7a7fdd.
Report an issue: GitHub.