{"record":{"id":"7ab85fcc59f1d3e6","repo":"skylot/jadx","slug":"orphaned-traverser-state","errorCode":null,"errorMessage":"Orphaned traverser state","messagePattern":"Orphaned traverser state","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java","lineNumber":32,"sourceCode":"\n\tpublic BaseBlockTraverserHandler(TraverserState initialState) {\n\t\tsuper(initialState);\n\t}\n\n\tpublic BaseBlockTraverserHandler(AtomicReference<TraverserState> initialStateRef) {\n\t\tsuper(initialStateRef);\n\t}\n\n\t@Override\n\tprotected void handle() {\n\t\tTraverserBlockInfo blockInsnInfo = getState().getBlockInsnInfo();\n\t\tif (blockInsnInfo == null) {\n\t\t\tthrow new JadxRuntimeException(\"Expected to find block info within \" + getClass().getSimpleName());\n\t\t}\n\t\tTraverserActivePathState comparator = getState().getComparatorState();\n\t\tAtomicReference<TraverserState> stateRef = comparator.getReferenceForState(getState());\n\t\tif (stateRef == null) {\n\t\t\tthrow new JadxRuntimeException(\"Orphaned traverser state\");\n\t\t}\n\t\tBlockNode block = blockInsnInfo.getBlock();\n\t\tImplicitInsnBlockTraverserVisitor implicitVisitor = new ImplicitInsnBlockTraverserVisitor(getState());\n\t\tTraverserState stateAfterImplicit = implicitVisitor.visit(block);\n\t\tPathEndBlockTraverserVisitor pathEndVisitor = new PathEndBlockTraverserVisitor(stateAfterImplicit);\n\t\tTraverserState nextState = pathEndVisitor.visit(block);\n\n\t\tstateRef.set(nextState);\n\t}\n}\n","sourceCodeStart":14,"sourceCodeEnd":43,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java#L14-L43","documentation":"Thrown by BaseBlockTraverserHandler.handle() when TraverserActivePathState.getReferenceForState() returns null for the current state. An active path holds exactly two state slots (finally and candidate) via AtomicReferences; getReferenceForState performs reference-identity checks against both. Returning null means the state being handled is not the finally or candidate state currently registered in its own comparator — the state graph has become detached or corrupted.","triggerScenarios":"A TraverserState object was duplicated or replaced (via stateRef.set()) but a stale reference to the previous state was still dispatched to a handler. Alternatively, a state was moved between active path instances during merge/duplicate operations without updating its comparatorState pointer.","commonSituations":"Decompiling APKs with intricate try-finally or synchronized-block patterns that trigger the scope-split merge path. The error surfaces when the finally traverser's state duplication logic produces a state that references a different TraverserActivePathState than the one that holds it.","solutions":["Report to the jadx project with the input APK/JAR and stack trace — this is an internal state-management bug.","Workaround: disable the finally extraction visitor pass for the problematic input.","Update to the latest jadx version; the traverser state lifecycle is under active refinement.","If patching jadx, audit TraverserActivePathState.duplicate() and produceFromFactories() to ensure the new state's comparatorState back-pointer matches the active path that holds the state's AtomicReference."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before handling, verify the state is still the live reference\nAtomicReference<TraverserState> ref = comparator.getReferenceForState(state);\nif (ref == null) {\n    // State is stale/orphaned; do not proceed\n    return;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Internal jadx state-management invariant; not user-guardable.","Ensure no stale state references survive duplication or merge operations.","If developing jadx, always use getReferenceForState() before writing results."],"tags":["jadx","decompiler","finally-traverser","state-management","reference-identity"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}