NationalSecurityAgency/ghidra · critical · IllegalStateException

Schema doesn't provide a unique {} for {}

Error message

Schema doesn't provide a unique {} for {}

What it means

Thrown as IllegalStateException by DBTraceStackManager.single when the given seed object's schema does not provide a unique (singleton) path to the requested target interface (e.g. TraceStack). searchFor(targetIf, false) must return a filter whose getSingletonPath() is non-null. If the schema allows zero or multiple candidate locations, the manager cannot deterministically locate the stack (or stack frame) and refuses to proceed.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStackManager.java:73

		this.threadManager = threadManager;
		this.overlayAdapter = overlayAdapter;
	}

	@Override
	public void dbError(IOException e) {
		trace.dbError(e);
	}

	@Override
	public void invalidateCache(boolean all) {
		// NOTE: This is only a wrapper around the object manager
	}

	public static PathFilter single(TraceObject seed,
			Class<? extends TraceObjectInterface> targetIf) {
		PathFilter stackFilter = seed.getSchema().searchFor(targetIf, false);
		if (stackFilter.getSingletonPath() == null) {
			throw new IllegalStateException("Schema doesn't provide a unique " +
				targetIf.getSimpleName() + " for " + seed.getCanonicalPath());
		}
		return stackFilter.getSingletonPattern();
	}

	protected TraceStack doGetOrAddObjectStack(TraceThread thread, long snap,
			boolean createIfAbsent) {
		TraceObject obj = thread.getObject();
		PathFilter filter = single(obj, TraceStack.class);
		if (createIfAbsent) {
			try (LockHold hold = trace.lockWrite()) {
				TraceStack stack =
					trace.getObjectManager().getSuccessor(obj, filter, snap, TraceStack.class);
				if (stack != null) {
					return stack;
				}
				KeyPath path = obj.getCanonicalPath().extend(filter.getSingletonPath());
				return trace.getObjectManager().addStack(path, snap);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure the schema pins exactly one path from the thread object to TraceStack (and to TraceStackFrame).
  2. Recreate the trace with the canonical framework schema.
  3. Use a lower-level object API to navigate explicitly when the schema is intentionally ambiguous.
Defensive patterns

Strategy: try-catch

Validate before calling

PathFilter f = seed.getSchema().searchFor(TraceStack.class, false);
if (f.getSingletonPath() == null) { /* schema ambiguous/absent */ }

Try / catch

try { stack = mgr.getOrAddObjectStack(thread, snap, true); }
catch (IllegalStateException e) { /* schema cannot locate stack uniquely */ }

Prevention

When it happens

Trigger: Calling getOrAddObjectStack on a thread whose schema defines no unique TraceStack, or defines multiple alternative paths to one. Custom schemas with branching elements for stacks/frames.

Common situations: Trace created with a non-standard or partial object schema; mixing schema versions; a connector that builds an ambiguous object tree.

Related errors


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