skylot/jadx · error · JadxRuntimeException

Orphaned TraverserState node

Error message

Orphaned TraverserState node

What it means

Thrown by TraverserActivePathState.getGlobalStateFor(TraverserState state) when the state argument is not the object currently held by either finallyStateRef or candidateStateRef. The method uses reference identity (==) to map a state to its global state group. This fires when a caller passes a state that is a duplicate or stale copy rather than the exact reference the active path currently holds.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java:331

	@Nullable
	public final AtomicReference<TraverserState> getReferenceForState(TraverserState state) {
		if (finallyStateRef.get() == state) {
			return finallyStateRef;
		}
		if (candidateStateRef.get() == state) {
			return candidateStateRef;
		}
		return null;
	}

	public final GlobalTraverserSourceState getGlobalStateFor(TraverserState state) {
		if (finallyStateRef.get() == state) {
			return finallyGlobalState;
		}
		if (candidateStateRef.get() == state) {
			return candidateGlobalState;
		}
		throw new JadxRuntimeException("Orphaned TraverserState node");
	}

	public final GlobalTraverserSourceState getFinallyGlobalState() {
		return finallyGlobalState;
	}

	public final GlobalTraverserSourceState getCandidateGlobalState() {
		return candidateGlobalState;
	}

	public final TraverserGlobalCommonState getGlobalCommonState() {
		return commonGlobalState;
	}

	public final void mergeWith(List<TraverserActivePathState> otherStates) {
		for (TraverserActivePathState otherState : otherStates) {
			matchedInsns.addAll(otherState.getMatchedInsns());

View on GitHub (pinned to e738a26571)

Solutions

  1. Report to jadx developers with the input file and full trace.
  2. Workaround: skip the finally visitor.
  3. If patching jadx, ensure that after every produceFromFactories() or duplicate() call, no stale state references are retained in handler queues or visitor-local variables.
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Called via TraverserState.getGlobalState() which delegates to getComparatorState().getGlobalStateFor(this). If 'this' is a duplicated state whose comparatorState points to an active path that holds a different state object in its slot, the identity check fails.

Common situations: State duplication during merge or branch operations produces a new state object, but an old reference to the pre-duplication state is still used to query global state. Happens with deeply nested finally blocks or synchronized regions.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/599632474336ffd5. Report an issue: GitHub.