oracle/graal · error · ElementException

Node field must be annotated with @${Input.getSimpleName()},

Error message

Node field must be annotated with @${Input.getSimpleName()}, @${OptionalInput.getSimpleName()} or @${Successor.getSimpleName()}

What it means

Any non-static field whose type is assignable to Node must be annotated with @Input, @OptionalInput or @Successor (the only exception is a field literally named 'Null', used for the null constant). Unannotated Node fields would be invisible to the graph: they would neither be tracked as usages nor serialized/visited, silently corrupting the graph. The processor scans the class and all superclasses when the node class is registered via @NodeInfo.

Source

Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java:166

                        }
                        if (modifiers.contains(PUBLIC)) {
                            throw new ElementException(field, "Successor list field must not be public");
                        }
                    } else {
                        if (!isAssignableWithErasure(field, Node)) {
                            throw new ElementException(field, "Successor field must be a Node type");
                        }
                        if (modifiers.contains(FINAL)) {
                            throw new ElementException(field, "Successor field must not be final");
                        }
                        if (modifiers.contains(PUBLIC)) {
                            throw new ElementException(field, "Successor field must not be public");
                        }
                    }

                } else {
                    if (isAssignableWithErasure(field, Node) && !field.getSimpleName().contentEquals("Null")) {
                        throw new ElementException(field, "Node field must be annotated with @" + Input.getSimpleName() + ", @" + OptionalInput.getSimpleName() + " or @" + Successor.getSimpleName());
                    }
                    if (isAssignableWithErasure(field, NodeInputList)) {
                        throw new ElementException(field, "NodeInputList field must be annotated with @" + Input.getSimpleName() + " or @" + OptionalInput.getSimpleName());
                    }
                    if (isAssignableWithErasure(field, NodeSuccessorList)) {
                        throw new ElementException(field, "NodeSuccessorList field must be annotated with @" + Successor.getSimpleName());
                    }
                    if (modifiers.contains(PUBLIC) && !modifiers.contains(FINAL)) {
                        throw new ElementException(field, "Data field must be final if public");
                    }
                }
            }
            currentClazz = getSuperType(currentClazz);
        } while (!isObject(getSuperType(currentClazz).asType()));
    }

    private AnnotationMirror findAnnotationMirror(List<? extends AnnotationMirror> mirrors, TypeElement expectedAnnotationType) {
        for (AnnotationMirror mirror : mirrors) {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Decide the edge kind and add @Input, @OptionalInput (value dependency) or @Successor (control-flow) to the field.
  2. If the field must stay outside the graph, mark it transient (transient fields are skipped by scanFields) or static.
  3. If it is a cache recomputed on demand, consider a transient field plus lazy recompute.
  4. Rebuild to confirm.

Example fix

// before
protected ValueNode cached;

// after
@OptionalInput
protected ValueNode cached;
// or, if not a graph edge:
transient protected ValueNode cached;
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: A field where isAssignableWithErasure(field, Node) is true, none of the three annotations is present, and field.getSimpleName() is not exactly 'Null' (GraphNodeVerifier.java:165-167). Example: 'protected ValueNode cached;' with no annotation in a @NodeInfo class.

Common situations: Adding a scratch/cache Node reference to a node class; forgetting the annotation on a newly added edge; subclassing an existing node and adding a Node-typed field; renaming a field to something other than 'Null' that previously relied on the exemption.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/178f1abe70fe4267. Report an issue: GitHub.