{"record":{"id":"80edcc3d9d471233","repo":"skylot/jadx","slug":"expected-to-find-block-info-within","errorCode":null,"errorMessage":"Expected to find block info within {}","messagePattern":"Expected to find block info within (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java","lineNumber":27,"sourceCode":"import jadx.core.dex.visitors.finaly.traverser.visitors.ImplicitInsnBlockTraverserVisitor;\nimport jadx.core.dex.visitors.finaly.traverser.visitors.PathEndBlockTraverserVisitor;\nimport jadx.core.utils.exceptions.JadxRuntimeException;\n\npublic class BaseBlockTraverserHandler extends AbstractBlockPathTraverserHandler {\n\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":9,"sourceCodeEnd":43,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/traverser/handlers/BaseBlockTraverserHandler.java#L9-L43","documentation":"Thrown by BaseBlockTraverserHandler.handle() when the current TraverserState's getBlockInsnInfo() returns null. The finally-block traverser subsystem requires every block-level handler state to carry a TraverserBlockInfo (the active block and its instruction offsets). A null value means the state type does not track an active block (e.g. a terminal, global, or cache-recovery state was incorrectly routed to this handler). This is an internal invariant violation in jadx's 'finaly' (finally-extraction) visitor pipeline, not a user-configuration error.","triggerScenarios":"A TraverserState subclass whose getUnderlyingBlockInsnInfo() returns null (such as TerminalTraverserState, a global source state, or a cache-recovery wrapper) is passed into a BaseBlockTraverserHandler via the traverser controller's getNextHandler() dispatch. This happens when a state transition produces a non-block state but the controller still routes it to a block-handling handler.","commonSituations":"Decompiling an APK/JAR that contains complex or unusual try-finally control flow that the finally-extraction algorithm does not handle. Rarely triggered on typical inputs; almost always indicates a logic gap in the finally visitor for a specific bytecode shape (e.g. nested finally blocks, finally blocks with exception handlers, or synthetic compiler-generated control flow).","solutions":["Report the issue to the jadx project with the input file and full stack trace — this is an internal decompiler bug in the finally visitor.","As a workaround, disable finally extraction by passing the decompiler argument to skip the finally pass (e.g. --no-debug-info or relevant visitor skip flags) and re-run.","Try a different jadx version — the finally traverser is under active development and the edge case may be fixed in a newer release.","If developing jadx itself, add a null check and inspect which concrete TraverserState subclass is being dispatched to a block handler; the state's getNextHandler() is returning the wrong handler type."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before dispatching a state to a block handler, verify it carries block info\nTraverserBlockInfo info = state.getBlockInsnInfo();\nif (info == null) {\n    // Skip or route to a non-block handler instead of throwing\n    return;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["This is an internal jadx invariant; end users cannot guard against it at the API level.","Keep jadx updated — the finally traverser is under active development.","If developing jadx, never route non-block TraverserState types (terminal, global, cache) to BaseBlockTraverserHandler."],"tags":["jadx","decompiler","finally-traverser","internal-invariant","state-machine"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}