{"record":{"id":"d89cba17eebdd7d6","repo":"TheAlgorithms/Java","slug":"invalid-root-root","errorCode":null,"errorMessage":"Invalid root: {root}","messagePattern":"Invalid root: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java","lineNumber":42,"sourceCode":"     *\n     * @param graph The graph that represents the tree and is used for the matching algorithm.\n     */\n    public TreeMatching(UndirectedAdjacencyListGraph graph) {\n        this.graph = graph;\n        this.dp = new int[graph.size()][2];\n    }\n\n    /**\n     * Calculates the maximum weighted matching for the tree, starting from the given root node.\n     *\n     * @param root The index of the root node of the tree.\n     * @param parent The index of the parent node (used for recursion).\n     * @return The maximum weighted matching for the tree, starting from the root node.\n     *\n     */\n    public int getMaxMatching(int root, int parent) {\n        if (root < 0 || root >= graph.size()) {\n            throw new IllegalArgumentException(\"Invalid root: \" + root);\n        }\n        maxMatching(root, parent);\n        return Math.max(dp[root][0], dp[root][1]);\n    }\n\n    /**\n     * Recursively computes the maximum weighted matching for a node, assuming that the node\n     * can either be included or excluded from the matching.\n     *\n     * @param node The index of the current node for which the matching is calculated.\n     * @param parent The index of the parent node (to avoid revisiting the parent node during recursion).\n     */\n    private void maxMatching(int node, int parent) {\n        dp[node][0] = 0;\n        dp[node][1] = 0;\n\n        int sumWithoutEdge = 0;\n        for (int adjNode : graph.getNeighbors(node)) {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/dynamicprogramming/TreeMatching.java#L24-L60","documentation":"Thrown by TreeMatching.getMaxMatching(int root, int parent) when root is outside [0, graph.size()). The DP table dp[root][0/1] is indexed by root, so an out-of-range index would throw ArrayIndexOutOfBoundsException; the library validates explicitly. Message: 'Invalid root: <root>'.","triggerScenarios":"Passing root = -1 (common sentinel for 'no parent'); root >= number of vertices; root computed from a vertex id that is 1-based while the graph is 0-based.","commonSituations":"Calling getMaxMatching on a tree where the root's parent is encoded as -1 and the root itself was passed -1 by mistake; mixing 1-based external ids with 0-based internal indices.","solutions":["Pass a valid root index in [0, graph.size()); use -1 only for the parent argument (which is not bounds-checked), not for root.","Convert external vertex ids to internal 0-based indices before calling.","Validate root against graph.size() at the call site."],"exampleFix":"// before\nint m = matcher.getMaxMatching(-1, -1); // wrong: -1 root\n\n// after\nint m = matcher.getMaxMatching(0, -1); // root 0, no parent","handlingStrategy":"validation","validationCode":"if (root < 0 || root >= graph.size()) {\n    throw new IllegalArgumentException(\"root out of range: \" + root);\n}\nmatcher.getMaxMatching(root, parent);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use -1 only for the parent argument, never for root.","Convert external 1-based vertex ids to internal 0-based indices.","Validate root against graph.size() at the call site."],"tags":["input-validation","index-out-of-bounds","graph","dynamic-programming"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}