{"record":{"id":"4497238291a5c6c8","repo":"skylot/jadx","slug":"loopregionvisitor-assignonlyinloop-endless-recursi","errorCode":null,"errorMessage":"LoopRegionVisitor.assignOnlyInLoop endless recursion","messagePattern":"LoopRegionVisitor\\.assignOnlyInLoop endless recursion","errorType":"exception","errorClass":"JadxOverflowException","httpStatus":null,"severity":"warning","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java","lineNumber":133,"sourceCode":"\t\tInsnNode initInsn = initArg.getAssignInsn();\n\t\tif (initInsn == null\n\t\t\t\t|| initInsn.contains(AFlag.DONT_GENERATE)\n\t\t\t\t|| initArg.getSVar().getUseCount() != 1) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!usedOnlyInLoop(mth, loopRegion, arg)) {\n\t\t\treturn false;\n\t\t}\n\t\t// can't make loop if argument from increment instruction is assign in loop\n\t\tList<RegisterArg> args = new ArrayList<>();\n\t\tincrInsn.getRegisterArgs(args);\n\t\tfor (RegisterArg iArg : args) {\n\t\t\ttry {\n\t\t\t\tif (assignOnlyInLoop(mth, loopRegion, iArg)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} catch (StackOverflowError error) {\n\t\t\t\tthrow new JadxOverflowException(\"LoopRegionVisitor.assignOnlyInLoop endless recursion\");\n\t\t\t}\n\t\t}\n\n\t\t// all checks passed\n\t\tinitInsn.add(AFlag.DONT_GENERATE);\n\t\tincrInsn.add(AFlag.DONT_GENERATE);\n\n\t\tLoopType arrForEach = checkArrayForEach(mth, loopRegion, initInsn, incrInsn, condition);\n\t\tloopRegion.setType(arrForEach != null ? arrForEach : new ForLoop(initInsn, incrInsn));\n\t\treturn true;\n\t}\n\n\tprivate static LoopType checkArrayForEach(MethodNode mth, LoopRegion loopRegion, InsnNode initInsn, InsnNode incrInsn,\n\t\t\tIfCondition condition) {\n\t\tif (!(incrInsn instanceof ArithNode)) {\n\t\t\treturn null;\n\t\t}\n\t\tArithNode arithNode = (ArithNode) incrInsn;","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java#L115-L151","documentation":"Thrown by LoopRegionVisitor.checkForLoop when the recursive helper assignOnlyInLoop throws a JVM StackOverflowError. jadx detects the SOError, converts it to a JadxOverflowException, and gives up converting that loop into a for/for-each loop. The method is still decompiled; only the loop-shape recognition for that one loop fails.","triggerScenarios":"Decompiling a method where the increment expression of a candidate for-loop references registers whose assignment chains are deeply or mutually recursive, so the recursive assignOnlyInLoop walk blows the JVM stack.","commonSituations":"Obfuscated loop code, loops with complex phi-derived indices, or nested loops where the increment variable feeds back through many SSA edges. The user-visible effect is usually that a loop renders as a while(true) with manual index update instead of a clean for-loop.","solutions":["Upgrade jadx; assignOnlyInLoop has been hardened and de-recursified over releases.","Run the JVM with a larger thread stack (-Xss) if you embed jadx and hit it on borderline inputs.","Ignore it - the method still decompiles, only the for-loop prettification is skipped.","Catch JadxOverflowException around the decompile call if you need the batch to keep going."],"exampleFix":"// before\njava -jar jadx-cli.jar app.apk\n// after - give the recursive helper more stack\njava -Xss4m -jar jadx-cli.jar app.apk","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    cls.decompile();\n} catch (JadxOverflowException e) {\n    if (e.getMessage().contains(\"assignOnlyInLoop endless recursion\")) {\n        cls.addError(\"loop-shape detection overflow\", e);\n    } else { throw e; }\n}","preventionTips":["Give the JVM a larger stack (-Xss4m) when embedding jadx against hard inputs.","Update jadx; assignOnlyInLoop is de-recursified over time.","This is non-fatal to output quality - only for-loop prettification is skipped."],"tags":["decompiler","loops","recursion","stack-overflow","for-loop"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}