{"record":{"id":"5b7cc2c8a3737f71","repo":"skylot/jadx","slug":"unexpected-missing-predecessor-for-block","errorCode":null,"errorMessage":"Unexpected missing predecessor for block: {}","messagePattern":"Unexpected missing predecessor for block: (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockSplitter.java","lineNumber":280,"sourceCode":"\t * This temporary connection is necessary to build close to a final dominator tree.\n\t * Will be used and removed in {@code jadx.core.dex.visitors.blocks.BlockExceptionHandler}\n\t */\n\tprivate static void addTempConnectionsForExcHandlers(MethodNode mth, Map<Integer, BlockNode> blocksMap) {\n\t\tif (mth.isNoExceptionHandlers()) {\n\t\t\treturn;\n\t\t}\n\t\tfor (BlockNode block : mth.getBasicBlocks()) {\n\t\t\tfor (InsnNode insn : block.getInstructions()) {\n\t\t\t\tCatchAttr catchAttr = insn.get(AType.EXC_CATCH);\n\t\t\t\tif (catchAttr == null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tfor (ExceptionHandler handler : catchAttr.getHandlers()) {\n\t\t\t\t\tBlockNode handlerBlock = getBlock(handler.getHandlerOffset(), blocksMap);\n\t\t\t\t\tif (!handlerBlock.contains(AType.TMP_EDGE)) {\n\t\t\t\t\t\tList<BlockNode> preds = block.getPredecessors();\n\t\t\t\t\t\tif (preds.isEmpty()) {\n\t\t\t\t\t\t\tthrow new JadxRuntimeException(\"Unexpected missing predecessor for block: \" + block);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tBlockNode start = preds.size() == 1 ? preds.get(0) : block;\n\t\t\t\t\t\tif (!start.getSuccessors().contains(handlerBlock)) {\n\t\t\t\t\t\t\tconnect(start, handlerBlock);\n\t\t\t\t\t\t\thandlerBlock.addAttr(new TmpEdgeAttr(start));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static void setupExitConnections(MethodNode mth) {\n\t\tBlockNode exitBlock = mth.getExitBlock();\n\t\tfor (BlockNode block : mth.getBasicBlocks()) {\n\t\t\tif (block.getSuccessors().isEmpty() && block != exitBlock) {\n\t\t\t\tconnect(block, exitBlock);\n\t\t\t\tif (BlockUtils.checkLastInsnType(block, InsnType.RETURN)) {","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockSplitter.java#L262-L298","documentation":"Thrown during exception handler edge setup in block splitting. For each instruction with an EXC_CATCH attribute, jadx connects the handler block to the appropriate predecessor. If the block containing the throwing instruction has zero predecessors, the connection point is undefined.","triggerScenarios":"A block containing an instruction with EXC_CATCH attribute has an empty predecessors list. The code needs at least one predecessor to establish the exception edge, so it throws when preds.isEmpty() is true.","commonSituations":"Malformed CFG where exception-throwing instructions exist in blocks with no incoming edges; block splitting produced a disconnected block; obfuscated bytecode with unusual exception table entries pointing to unreachable code.","solutions":["Update jadx — exception edge setup is frequently hardened against edge cases","Report the APK as a jadx issue","Verify the DEX exception table with baksmali to check for malformed entries","Decompile classes individually to isolate the problem method"],"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(\"Unexpected missing predecessor\")) {\n        LOG.warn(\"Exception edge setup inconsistency, skipping problematic class\");\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":["Verify DEX exception tables with baksmali for malformed entries","Keep jadx updated — exception edge setup is frequently hardened","Report the APK as a jadx issue","Decompile classes individually to isolate the problematic method"],"tags":["block-splitter","exception-handling","control-flow","decompiler"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}