oracle/graal · error · IllegalStateException
Using add for value numberable node. Consider using either u
Error message
Using add for value numberable node. Consider using either unique or addWithoutUnique.
What it means
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.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/Graph.java:511
return nodesDeletedSinceLastCompression;
}
/**
* Gets the total number of nodes which have been deleted from this graph.
*/
public int getTotalNodesDeleted() {
return nodesDeletedSinceLastCompression + nodesDeletedBeforeLastCompression;
}
/**
* Adds a new node to the graph.
*
* @param node the node to be added
* @return the node which was added to the graph
*/
public <T extends Node> T add(T node) {
if (node.getNodeClass().valueNumberable()) {
throw new IllegalStateException("Using add for value numberable node. Consider using either unique or addWithoutUnique.");
}
return addHelper(node);
}
public <T extends Node> T addWithoutUnique(T node) {
return addHelper(node);
}
/**
* Returns {@code node} if it is alive in this graph. Otherwise, looks for an existing, GVN
* equivalent node and returns it if found. If no such node is found, {@code node} is added to
* this graph and returned.
* <p>
* The return value of this function should not be ignored. If the return value is not assigned
* to {@code node}, {@code node} should not be used afterwards:
*
* <pre>
* x = ...;View on GitHub (pinned to a66e9ccd1d)
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.
Example fix
// before graph.add(ConstantNode.forInt(1, graph)); // IllegalStateException if via add() // after ConstantNode one = graph.unique(ConstantNode.forInt(1, graph));
Defensive patterns
Strategy: type-guard
Validate before calling
static <T extends Node> T addToGraph(Graph g, T node) {
return node.getNodeClass().valueNumberable() ? g.unique(node) : g.add(node);
} Type guard
static boolean isValueNumberable(Node n) {
return n.getNodeClass().valueNumberable();
}
// usage: isValueNumberable(node) ? graph.unique(node) : graph.add(node) Prevention
- 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().
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- %s must not kill %s
- Couldn't find method bridged by %s:%n%s
- No opcode for %s
- not implemented
- isEmpty() is not supported for performance reasons
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/181cbf928f5db013.
Report an issue: GitHub.