{"record":{"id":"cca0c78274a4a38e","repo":"TheAlgorithms/Java","slug":"successors-and-predecessors-must-not-be-null","errorCode":null,"errorMessage":"successors and predecessors must not be null","messagePattern":"successors and predecessors must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java","lineNumber":95,"sourceCode":"     * @return immutable list of traversal events (VISITs with monotonically increasing order and SKIPs with messages)\n     * @throws IllegalArgumentException if {@code successors} is null\n     */\n    public static <T> List<TraversalEvent<T>> dfsRecursiveOrder(Map<T, List<T>> successors, T start) {\n        if (successors == null) {\n            throw new IllegalArgumentException(\"successors must not be null\");\n        }\n        // derive predecessors once\n        Map<T, List<T>> predecessors = derivePredecessors(successors);\n        return dfsRecursiveOrder(successors, predecessors, start);\n    }\n\n    /**\n     * Same as {@link #dfsRecursiveOrder(Map, Object)} but with an explicit predecessors map.\n     */\n    public static <T> List<TraversalEvent<T>> dfsRecursiveOrder(Map<T, List<T>> successors, Map<T, List<T>> predecessors, T start) {\n\n        if (successors == null || predecessors == null) {\n            throw new IllegalArgumentException(\"successors and predecessors must not be null\");\n        }\n        if (start == null) {\n            return List.of();\n        }\n        if (!successors.containsKey(start) && !appearsAnywhere(successors, start)) {\n            return List.of(); // start not present in graph\n        }\n\n        List<TraversalEvent<T>> events = new ArrayList<>();\n        Set<T> visited = new HashSet<>();\n        int[] order = {0};\n        dfs(start, successors, predecessors, visited, order, events);\n        return Collections.unmodifiableList(events);\n    }\n\n    private static <T> void dfs(T currentNode, Map<T, List<T>> successors, Map<T, List<T>> predecessors, Set<T> visited, int[] order, List<TraversalEvent<T>> result) {\n\n        if (!visited.add(currentNode)) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java#L77-L113","documentation":"PredecessorConstrainedDfs.dfsRecursiveOrder(successors, predecessors, start) (the two-map overload) throws this IllegalArgumentException when either the successors or predecessors map is null. This overload requires both maps to be pre-built and consistent.","triggerScenarios":"Calling the three-argument overload with successors null, predecessors null, or both null.","commonSituations":"Passing a derived predecessors map that was never computed. Mismatch between the single-arg and two-arg overloads where callers forget to supply predecessors. Field injection leaving one map null.","solutions":["Use the single-argument overload if you only have successors; it derives predecessors for you.","If calling the two-argument overload, build predecessors first via the same derivePredecessors logic.","Guard: if either map is null, fall back to the single-arg overload."],"exampleFix":"// before\nList<TraversalEvent<T>> e = PredecessorConstrainedDfs.dfsRecursiveOrder(successors, null, start);\n\n// after\nList<TraversalEvent<T>> e = PredecessorConstrainedDfs.dfsRecursiveOrder(successors, start); // single-arg derives predecessors","handlingStrategy":"validation","validationCode":"if (successors == null || predecessors == null) {\n    // fall back to single-arg overload which derives predecessors\n    return PredecessorConstrainedDfs.dfsRecursiveOrder(successors, start);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer the single-argument overload when you only have successors.","Derive predecessors with the same logic the library uses.","Guard both maps against null before calling the two-arg overload."],"tags":["graph-algorithm","argument-validation","null-check","dfs"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}