TheAlgorithms/Java · error · IllegalArgumentException

successors must not be null

Error message

successors must not be null

What it means

PredecessorConstrainedDfs.dfsRecursiveOrder(successors, start) throws this IllegalArgumentException when the successors adjacency map is null. The single-argument overload derives predecessors internally, so it only needs to guard the successors parameter.

Source

Thrown at src/main/java/com/thealgorithms/graph/PredecessorConstrainedDfs.java:82

        }
    }

    /**
     * DFS (recursive) that records the order of first visit starting at {@code start},
     * but only recurses to a child when <b>all</b> its predecessors have been visited.
     * If a child is encountered early (some parent unvisited), a SKIP event is recorded.
     *
     * <p>Equivalent idea to the Python pseudo in the user's description (with successors and predecessors),
     * but implemented in Java and returning a sequence of {@link TraversalEvent}s.</p>
     *
     * @param successors adjacency list: for each node, its outgoing neighbors
     * @param start start node
     * @return immutable list of traversal events (VISITs with monotonically increasing order and SKIPs with messages)
     * @throws IllegalArgumentException if {@code successors} is null
     */
    public static <T> List<TraversalEvent<T>> dfsRecursiveOrder(Map<T, List<T>> successors, T start) {
        if (successors == null) {
            throw new IllegalArgumentException("successors must not be null");
        }
        // derive predecessors once
        Map<T, List<T>> predecessors = derivePredecessors(successors);
        return dfsRecursiveOrder(successors, predecessors, start);
    }

    /**
     * Same as {@link #dfsRecursiveOrder(Map, Object)} but with an explicit predecessors map.
     */
    public static <T> List<TraversalEvent<T>> dfsRecursiveOrder(Map<T, List<T>> successors, Map<T, List<T>> predecessors, T start) {

        if (successors == null || predecessors == null) {
            throw new IllegalArgumentException("successors and predecessors must not be null");
        }
        if (start == null) {
            return List.of();
        }
        if (!successors.containsKey(start) && !appearsAnywhere(successors, start)) {

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Pass an empty map (Collections.emptyMap()) instead of null for a trivial graph.
  2. Ensure the successors map is constructed before the DFS call.
  3. Add a null guard returning an empty event list.

Example fix

// before
List<TraversalEvent<T>> events = PredecessorConstrainedDfs.dfsRecursiveOrder(successors, start);

// after
Map<T, List<T>> succ = successors != null ? successors : Map.of();
List<TraversalEvent<T>> events = PredecessorConstrainedDfs.dfsRecursiveOrder(succ, start);
Defensive patterns

Strategy: validation

Validate before calling

if (successors == null) {
    successors = java.util.Collections.emptyMap();
}

Type guard

boolean hasSuccessors(Map<?,?> succ) { return succ != null; }

Prevention

When it happens

Trigger: Calling dfsRecursiveOrder(null, start) with a null adjacency map.

Common situations: Graph not yet built when the traversal is triggered. A field left null after failed initialization. Optional/empty graph represented as null instead of an empty map.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/32539bc6063ac5aa. Report an issue: GitHub.