{"record":{"id":"d9be299c4fc938a5","repo":"oracle/graal","slug":"node-class-constructor-must-be-public-or-protected","errorCode":null,"errorMessage":"Node class constructor must be public or protected","messagePattern":"Node class constructor must be public or protected","errorType":"validation","errorClass":"ElementException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java","lineNumber":215,"sourceCode":"        return processor.env().getTypeUtils().isSameType(type1, type2);\n    }\n\n    private TypeElement getSuperType(TypeElement element) {\n        if (element.getSuperclass() != null) {\n            return processor.asTypeElement(element.getSuperclass());\n        }\n        return null;\n    }\n\n    void verify(TypeElement node) {\n        scanFields(node);\n\n        boolean foundValidConstructor = false;\n        for (ExecutableElement constructor : ElementFilter.constructorsIn(node.getEnclosedElements())) {\n            if (constructor.getModifiers().contains(PRIVATE)) {\n                continue;\n            } else if (!constructor.getModifiers().contains(PUBLIC) && !constructor.getModifiers().contains(PROTECTED)) {\n                throw new ElementException(constructor, \"Node class constructor must be public or protected\");\n            }\n\n            foundValidConstructor = true;\n        }\n\n        if (!foundValidConstructor) {\n            throw new ElementException(node, \"Node class must have at least one protected constructor\");\n        }\n    }\n}\n","sourceCodeStart":197,"sourceCodeEnd":226,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java#L197-L226","documentation":"Every declared constructor of a @NodeInfo node class must be public or protected (private ones are simply skipped as internal helpers, e.g. for vannatable constructors). Package-private constructors would prevent the generated node metas and instantiation machinery from creating the node reliably across packages. GraphNodeVerifier throws this ElementException on the offending constructor during annotation processing.","triggerScenarios":"A constructor whose modifiers contain neither PRIVATE, PUBLIC nor PROTECTED — i.e. package-private — is found by ElementFilter.constructorsIn(node.getEnclosedElements()) (GraphNodeVerifier.java:211-216). Example: 'MyNode(ValueNode x) { ... }' with no visibility modifier.","commonSituations":"Adding a helper constructor without an access modifier (Java defaults to package-private); refactoring visibility during test wiring; nodes in packages different from where they are instantiated.","solutions":["Add protected or public to the constructor declaration.","If the constructor is internal-only, make it private so the verifier skips it — but then ensure at least one non-private constructor remains (else error 'Node class must have at least one protected constructor' follows).","Rebuild to confirm."],"exampleFix":"// before\nMyNode(ValueNode x) {\n    super(...);\n}\n\n// after\nprotected MyNode(ValueNode x) {\n    super(...);\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write an explicit access modifier on node constructors (Java's default package-private is rejected).","Keep node constructors protected unless the node is meant to be instantiated broadly."],"tags":["java","graalvm","annotation-processing","graal-node","constructors","compile-time"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}