oracle/graal · error · ElementException

Input list field must not be public

Error message

Input list field must not be public

What it means

The NodeInfo processor rejects NodeInputList fields annotated with @Input/@OptionalInput that are declared public. Public input lists would let arbitrary code bypass the node's encapsulated mutation methods and corrupt graph invariants (input lists must only be mutated through the node's API so usages are updated). The check runs for every non-static, non-transient field in the node class and all its superclasses.

Source

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

                }

                List<? extends AnnotationMirror> annotations = field.getAnnotationMirrors();

                boolean isNonOptionalInput = findAnnotationMirror(annotations, Input) != null;
                boolean isOptionalInput = findAnnotationMirror(annotations, OptionalInput) != null;
                boolean isSuccessor = findAnnotationMirror(annotations, Successor) != null;

                if (isNonOptionalInput || isOptionalInput) {
                    if (findAnnotationMirror(annotations, Successor) != null) {
                        throw new ElementException(field, "Field cannot be both input and successor");
                    } else if (isNonOptionalInput && isOptionalInput) {
                        throw new ElementException(field, "Inputs must be either optional or non-optional");
                    } else if (isAssignableWithErasure(field, NodeInputList)) {
                        if (modifiers.contains(FINAL)) {
                            throw new ElementException(field, "Input list field must not be final");
                        }
                        if (modifiers.contains(PUBLIC)) {
                            throw new ElementException(field, "Input list field must not be public");
                        }
                    } else {
                        if (!isAssignableWithErasure(field, Node) && field.getKind() == ElementKind.INTERFACE) {
                            throw new ElementException(field, "Input field type must be an interface or assignable to Node");
                        }
                        if (modifiers.contains(FINAL)) {
                            throw new ElementException(field, "Input field must not be final");
                        }
                        if (modifiers.contains(PUBLIC)) {
                            throw new ElementException(field, "Input field must not be public");
                        }
                    }
                } else if (isSuccessor) {
                    if (isAssignableWithErasure(field, NodeSuccessorList)) {
                        if (modifiers.contains(FINAL)) {
                            throw new ElementException(field, "Successor list field must not be final");
                        }
                        if (modifiers.contains(PUBLIC)) {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Change the field's visibility from public to protected or package-private.
  2. If external readers need the list, expose a read-only accessor (e.g. a getter returning the list or an unmodifiable view) instead of the field itself.
  3. Rebuild with mx build to verify the annotation processor passes.

Example fix

// before
@Input
public NodeInputList<ValueNode> values;

// after
@Input
protected NodeInputList<ValueNode> values;
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: scanFields() sees modifiers.contains(PUBLIC) on a field that has @Input or @OptionalInput and whose erased type is assignable to NodeInputList. Example: '@Input public NodeInputList<Stamp> stamps'.

Common situations: New node classes modeled after public-API value objects; Lombok/records-style classes pasted into the compiler; refactoring a helper class into a Node without tightening visibility; auto-generated IDE constructors exposing fields.

Related errors


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