{"record":{"id":"181cbf928f5db013","repo":"oracle/graal","slug":"using-add-for-value-numberable-node-consider-usin","errorCode":null,"errorMessage":"Using add for value numberable node. Consider using either unique or addWithoutUnique.","messagePattern":"Using add for value numberable node\\. Consider using either unique or addWithoutUnique\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Graph.java","lineNumber":511,"sourceCode":"        return nodesDeletedSinceLastCompression;\n    }\n\n    /**\n     * Gets the total number of nodes which have been deleted from this graph.\n     */\n    public int getTotalNodesDeleted() {\n        return nodesDeletedSinceLastCompression + nodesDeletedBeforeLastCompression;\n    }\n\n    /**\n     * Adds a new node to the graph.\n     *\n     * @param node the node to be added\n     * @return the node which was added to the graph\n     */\n    public <T extends Node> T add(T node) {\n        if (node.getNodeClass().valueNumberable()) {\n            throw new IllegalStateException(\"Using add for value numberable node. Consider using either unique or addWithoutUnique.\");\n        }\n        return addHelper(node);\n    }\n\n    public <T extends Node> T addWithoutUnique(T node) {\n        return addHelper(node);\n    }\n\n    /**\n     * Returns {@code node} if it is alive in this graph. Otherwise, looks for an existing, GVN\n     * equivalent node and returns it if found. If no such node is found, {@code node} is added to\n     * this graph and returned.\n     * <p>\n     * The return value of this function should not be ignored. If the return value is not assigned\n     * to {@code node}, {@code node} should not be used afterwards:\n     *\n     * <pre>\n     * x = ...;","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Graph.java#L493-L529","documentation":"Graph.add(node) refuses nodes whose NodeClass is value-numberable (i.e. eligible for global value numbering / GVN). Value-numberable nodes must go through unique() so duplicates are collapsed, or explicitly bypass GVN with addWithoutUnique(). Calling add() directly would silently defeat GVN, so it is guarded by this IllegalStateException.","triggerScenarios":"Programmatic graph construction (GRAAL IR manipulation, snippets, plugins, test code) calling graph.add(someConstantOrArithmeticNode) where the node class was generated with @NodeInfo(valueNumberable=true) — constants, arithmetic, compare nodes and most floating nodes. add() is only for non-value-numberable nodes such as FixedNodes (control-flow nodes, Begin/End, most stateful nodes).","commonSituations":"Writing custom Graal phases or graph transformers; porting code that manipulated a different IR; constructing graphs in unit tests. The exception names both legal alternatives in its message, making the fix mechanical once the intent (dedup vs. explicit node) is decided.","solutions":["If the node represents a pure value, use graph.unique(node) — it returns an existing GVN-equivalent node when one exists.","If you deliberately need a distinct node instance, use graph.addWithoutUnique(node).","Reserve graph.add() for nodes that are not value-numberable (fixed/control nodes); check node.getNodeClass().valueNumberable() when unsure."],"exampleFix":"// before\ngraph.add(ConstantNode.forInt(1, graph)); // IllegalStateException if via add()\n\n// after\nConstantNode one = graph.unique(ConstantNode.forInt(1, graph));","handlingStrategy":"type-guard","validationCode":"static <T extends Node> T addToGraph(Graph g, T node) {\n    return node.getNodeClass().valueNumberable() ? g.unique(node) : g.add(node);\n}","typeGuard":"static boolean isValueNumberable(Node n) {\n    return n.getNodeClass().valueNumberable();\n}\n// usage: isValueNumberable(node) ? graph.unique(node) : graph.add(node)","tryCatchPattern":null,"preventionTips":["Route all programmatic node insertion through one helper that checks valueNumberable() and picks unique() vs add().","Remember fixed/control nodes go to add(); floating pure values (constants, arithmetic) go to unique()."],"tags":["graph-ir","gvn","api-misuse","compiler-frontend","illegal-state"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}