{"record":{"id":"599632474336ffd5","repo":"skylot/jadx","slug":"orphaned-traverserstate-node","errorCode":null,"errorMessage":"Orphaned TraverserState node","messagePattern":"Orphaned TraverserState node","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java","lineNumber":331,"sourceCode":"\t@Nullable\n\tpublic final AtomicReference<TraverserState> getReferenceForState(TraverserState state) {\n\t\tif (finallyStateRef.get() == state) {\n\t\t\treturn finallyStateRef;\n\t\t}\n\t\tif (candidateStateRef.get() == state) {\n\t\t\treturn candidateStateRef;\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic final GlobalTraverserSourceState getGlobalStateFor(TraverserState state) {\n\t\tif (finallyStateRef.get() == state) {\n\t\t\treturn finallyGlobalState;\n\t\t}\n\t\tif (candidateStateRef.get() == state) {\n\t\t\treturn candidateGlobalState;\n\t\t}\n\t\tthrow new JadxRuntimeException(\"Orphaned TraverserState node\");\n\t}\n\n\tpublic final GlobalTraverserSourceState getFinallyGlobalState() {\n\t\treturn finallyGlobalState;\n\t}\n\n\tpublic final GlobalTraverserSourceState getCandidateGlobalState() {\n\t\treturn candidateGlobalState;\n\t}\n\n\tpublic final TraverserGlobalCommonState getGlobalCommonState() {\n\t\treturn commonGlobalState;\n\t}\n\n\tpublic final void mergeWith(List<TraverserActivePathState> otherStates) {\n\t\tfor (TraverserActivePathState otherState : otherStates) {\n\t\t\tmatchedInsns.addAll(otherState.getMatchedInsns());\n","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/state/TraverserActivePathState.java#L313-L349","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Report to jadx developers with the input file and full trace.","Workaround: skip the finally visitor.","If patching jadx, ensure that after every produceFromFactories() or duplicate() call, no stale state references are retained in handler queues or visitor-local variables."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reference-identity invariant; only the exact object held by finallyStateRef or candidateStateRef is valid.","If developing jadx, never query global state on a duplicated/stale state; always use the current reference from the active path.","Report inputs that trigger this with the full stack trace."],"tags":["jadx","decompiler","finally-traverser","reference-identity","global-state","internal-invariant"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}