{"record":{"id":"080260b570d21162","repo":"skylot/jadx","slug":"a-traverser-handler-which-was-not-expected-to-chan","errorCode":null,"errorMessage":"A traverser handler which was not expected to change path states actually did","messagePattern":"A traverser handler which was not expected to change path states actually did","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"critical","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java","lineNumber":183,"sourceCode":"\t\treturn List.of(state);\n\t}\n\n\t/**\n\t * Advances a singular state once.\n\t *\n\t * @return Whether this state has been aborted by the state abort function.\n\t */\n\tprivate boolean advanceSingleState(TraverserActivePathState activePathState, TraverserState singleState,\n\t\t\tboolean hasReadyToCompare) throws TraverserException {\n\t\tboolean stateAborted = stateAbortCondition != null && stateAbortCondition.apply(singleState);\n\t\tif (stateAbortCondition == null || !stateAborted) {\n\t\t\tif (singleState.getCompareState() == TraverserState.ComparisonState.NOT_READY\n\t\t\t\t\t|| singleState.getCompareState() == TraverserState.ComparisonState.AWAITING_OPTIONAL_PREDECESSOR_MERGE\n\t\t\t\t\t\t\t&& hasReadyToCompare) {\n\t\t\t\tAbstractBlockTraverserHandler handler = singleState.getNextHandler();\n\t\t\t\tList<TraverserActivePathState> results = processHandlerImplementations(activePathState, handler);\n\t\t\t\tif (results.size() != 1 || results.get(0) != activePathState) {\n\t\t\t\t\tthrow new JadxRuntimeException(\"A traverser handler which was not expected to change path states actually did\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn stateAborted;\n\t}\n}\n","sourceCodeStart":165,"sourceCodeEnd":190,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/TraverserController.java#L165-L190","documentation":"Thrown in the TraverserController when processing a single traverser state. A handler in the NOT_READY or AWAITING_OPTIONAL_PREDECESSOR_MERGE comparison state is expected to process in-place — returning exactly one result that is the same active path state object. If the handler returns a different result count or a different state object, the in-place processing invariant is violated.","triggerScenarios":"processHandlerImplementations returns a list with size != 1 or where results.get(0) is not the same object reference as activePathState. The handler split, merged, or replaced the path state when it was contractually required to modify in-place.","commonSituations":"Internal inconsistency in the traverser state machine — a handler incorrectly modifies path states when it should only update internal state; typically a jadx development bug in the finally-block traversal logic, not input-driven.","solutions":["Update jadx — traverser state machine bugs are patched promptly","Report as a jadx issue with the full stack trace and APK if available","This is an internal contract violation; not fixable from user input"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    jadxDecompiler.load();\n    jadxDecompiler.save();\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().contains(\"not expected to change path states\")) {\n        LOG.error(\"Internal jadx traverser state machine bug — update jadx\", e);\n        for (ClassNode cls : jadxDecompiler.getClasses()) {\n            try {\n                jadxDecompiler.decompileClass(cls);\n            } catch (JadxRuntimeException ex) {\n                LOG.warn(\"Skipped: {}\", cls.getFullName());\n            }\n        }\n    } else {\n        throw e;\n    }\n}","preventionTips":["Update jadx — this is an internal contract violation in the traverser state machine","Report as a jadx issue with the full stack trace","Decompile classes individually to isolate and skip the problematic class","Use an alternative decompiler as fallback for the affected class"],"tags":["traverser","internal-bug","state-machine","finally-block","decompiler"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}