oracle/graal · error · ElementException

Input field must not be public

Error message

Input field must not be public

What it means

Single-valued input fields (@Input/@OptionalInput, non-list) must not be public. Public input fields would allow uncontrolled mutation of graph edges, breaking the usage-tracking invariants the generated node code maintains (inputs must be changed via methods that update usages lists). This is a compile-time check performed over the node class and all superclasses.

Source

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

                        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)) {
                            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)) {

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Reduce the field's visibility to protected or package-private.
  2. Expose read access via a getter if callers need the input value.
  3. Rebuild with mx build to confirm.

Example fix

// before
@Input
public ValueNode value;

// after
@Input
protected ValueNode value;
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: modifiers.contains(PUBLIC) on an @Input/@OptionalInput field in the non-NodeInputList branch at GraphNodeVerifier.java:140-142, e.g. '@Input public ValueNode value;'.

Common situations: Node classes written like public data carriers; generated code that emits public fields; refactoring a public struct into a Node while keeping field visibility.

Related errors


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