{"record":{"id":"4c43acb7391cf153","repo":"oracle/graal","slug":"input-list-field-must-not-be-public","errorCode":null,"errorMessage":"Input list field must not be public","messagePattern":"Input list field must not be public","errorType":"validation","errorClass":"ElementException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java","lineNumber":131,"sourceCode":"                }\n\n                List<? extends AnnotationMirror> annotations = field.getAnnotationMirrors();\n\n                boolean isNonOptionalInput = findAnnotationMirror(annotations, Input) != null;\n                boolean isOptionalInput = findAnnotationMirror(annotations, OptionalInput) != null;\n                boolean isSuccessor = findAnnotationMirror(annotations, Successor) != null;\n\n                if (isNonOptionalInput || isOptionalInput) {\n                    if (findAnnotationMirror(annotations, Successor) != null) {\n                        throw new ElementException(field, \"Field cannot be both input and successor\");\n                    } else if (isNonOptionalInput && isOptionalInput) {\n                        throw new ElementException(field, \"Inputs must be either optional or non-optional\");\n                    } else if (isAssignableWithErasure(field, NodeInputList)) {\n                        if (modifiers.contains(FINAL)) {\n                            throw new ElementException(field, \"Input list field must not be final\");\n                        }\n                        if (modifiers.contains(PUBLIC)) {\n                            throw new ElementException(field, \"Input list field must not be public\");\n                        }\n                    } else {\n                        if (!isAssignableWithErasure(field, Node) && field.getKind() == ElementKind.INTERFACE) {\n                            throw new ElementException(field, \"Input field type must be an interface or assignable to Node\");\n                        }\n                        if (modifiers.contains(FINAL)) {\n                            throw new ElementException(field, \"Input field must not be final\");\n                        }\n                        if (modifiers.contains(PUBLIC)) {\n                            throw new ElementException(field, \"Input field must not be public\");\n                        }\n                    }\n                } else if (isSuccessor) {\n                    if (isAssignableWithErasure(field, NodeSuccessorList)) {\n                        if (modifiers.contains(FINAL)) {\n                            throw new ElementException(field, \"Successor list field must not be final\");\n                        }\n                        if (modifiers.contains(PUBLIC)) {","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java#L113-L149","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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.","solutions":["Change the field's visibility from public to protected or package-private.","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.","Rebuild with mx build to verify the annotation processor passes."],"exampleFix":"// before\n@Input\npublic NodeInputList<ValueNode> values;\n\n// after\n@Input\nprotected NodeInputList<ValueNode> values;","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep input-list fields protected or package-private; expose read access via getters.","Never auto-widen node field visibility for tests; add accessor methods instead.","Run mx checkstyle and mx build on new node classes to catch both style and processor errors."],"tags":["java","graalvm","annotation-processing","graal-node","encapsulation","compile-time"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}