{"record":{"id":"0429f2e03a6f627e","repo":"skylot/jadx","slug":"ordering-pass-not-found-listed-in-runbefore","errorCode":null,"errorMessage":"Ordering pass not found: {}, listed in 'runBefore' of pass: {}\n all passes: {}","messagePattern":"Ordering pass not found: (.+?), listed in 'runBefore' of pass: (.+?)\n all passes: (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/utils/PassMerge.java","lineNumber":95,"sourceCode":"\t\t\t\t\t// ignore known passes\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new JadxRuntimeException(\"Ordering pass not found: \" + name\n\t\t\t\t\t\t+ \", listed in 'runAfter' of pass: \" + pass\n\t\t\t\t\t\t+ \"\\n all passes: \" + ListUtils.map(visitors, namesMap::get));\n\t\t\t}\n\t\t}\n\t\tint before = Integer.MAX_VALUE;\n\t\tfor (String name : runBefore) {\n\t\t\tInteger pos = namePosMap.get(name);\n\t\t\tif (pos != null) {\n\t\t\t\tbefore = Math.min(before, pos);\n\t\t\t} else {\n\t\t\t\tif (mergePassesNames.contains(name)) {\n\t\t\t\t\t// ignore known passes\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new JadxRuntimeException(\"Ordering pass not found: \" + name\n\t\t\t\t\t\t+ \", listed in 'runBefore' of pass: \" + pass\n\t\t\t\t\t\t+ \"\\n all passes: \" + ListUtils.map(visitors, namesMap::get));\n\t\t\t}\n\t\t}\n\t\tif (before <= after) {\n\t\t\tthrow new JadxRuntimeException(\"Conflict order requirements for pass: \" + pass\n\t\t\t\t\t+ \"\\n run after: \" + runAfter\n\t\t\t\t\t+ \"\\n run before: \" + runBefore\n\t\t\t\t\t+ \"\\n passes: \" + ListUtils.map(visitors, namesMap::get));\n\t\t}\n\t\tif (after == -1) {\n\t\t\tif (before == Integer.MAX_VALUE) {\n\t\t\t\t// not ordered, put at last\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\treturn before;\n\t\t}\n\t\tint pos = after + 1;","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/utils/PassMerge.java#L77-L113","documentation":"Mirror of the runAfter case: PassMerge.searchInsertPos() iterates runBefore() and throws when a listed name is not found in the visitor position map and is not a known merge pass. The message names the missing pass, the pass that declared it, and the full pass list. Unlike runAfter, an unresolved runBefore name cannot be satisfied, so the pass cannot be positioned and the merge aborts.","triggerScenarios":"A custom JadxPass declares info().runBefore(\"foo\") where \"foo\" is absent from built-in visitors and not a registered merge pass. Raised in the runBefore loop at PassMerge line 95.","commonSituations":"Version skew after a jadx upgrade that renamed/removed a pass you tried to run before; typo in runBefore(); depending on a custom pass that another (not-yet-loaded) plugin should have provided.","solutions":["Match the runBefore() name to an entry in the 'all passes:' list shown in the error.","Align your plugin's jadx-api version with the running jadx to avoid referencing removed/renamed passes.","If the target is a custom pass, make sure that pass's plugin is loaded (appears in mergePassesNames) before declaring runBefore.","Use JadxPassInfo.END to run last, or remove the runBefore entry if strict ordering is unnecessary."],"exampleFix":"// before\nnew JadxPassInfo(\"my-pass\", \"my pass\").runBefore(\"ClassModifier\"); // wrong name\n// after\nnew JadxPassInfo(\"my-pass\", \"my pass\").runBefore(\"ClassModifierVisitor\"); // exact name","handlingStrategy":"validation","validationCode":"Set<String> known = visitors.stream().map(IDexTreeVisitor::getName).collect(Collectors.toSet());\nfor (String n : passInfo.runBefore()) {\n    if (!known.contains(n) && !mergePassNames.contains(n)\n        && !JadxPassInfo.START.equals(n) && !JadxPassInfo.END.equals(n)) {\n        throw new IllegalArgumentException(\"runBefore references unknown pass: \" + n);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    passMerge.merge(customPasses, wrapFn);\n} catch (JadxRuntimeException e) {\n    LOG.error(\"Pass merge failed (check runBefore names/version): {}\", e.getMessage());\n    throw e;\n}","preventionTips":["Keep plugin jadx-api version aligned with the running jadx.","Derive pass names from source, not memory.","After a jadx upgrade, re-validate your runBefore() names against the new pass list.","Use START/END sentinels where strict ordering is unnecessary."],"tags":["jadx","plugins","pass-ordering","configuration"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}