{"record":{"id":"74ded28619e84c40","repo":"oracle/graal","slug":"successor-field-must-be-a-node-type","errorCode":null,"errorMessage":"Successor field must be a Node type","messagePattern":"Successor field must be a Node type","errorType":"validation","errorClass":"ElementException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java","lineNumber":154,"sourceCode":"                        }\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)) {\n                            throw new ElementException(field, \"Successor list field must not be public\");\n                        }\n                    } else {\n                        if (!isAssignableWithErasure(field, Node)) {\n                            throw new ElementException(field, \"Successor field must be a Node type\");\n                        }\n                        if (modifiers.contains(FINAL)) {\n                            throw new ElementException(field, \"Successor field must not be final\");\n                        }\n                        if (modifiers.contains(PUBLIC)) {\n                            throw new ElementException(field, \"Successor field must not be public\");\n                        }\n                    }\n\n                } else {\n                    if (isAssignableWithErasure(field, Node) && !field.getSimpleName().contentEquals(\"Null\")) {\n                        throw new ElementException(field, \"Node field must be annotated with @\" + Input.getSimpleName() + \", @\" + OptionalInput.getSimpleName() + \" or @\" + Successor.getSimpleName());\n                    }\n                    if (isAssignableWithErasure(field, NodeInputList)) {\n                        throw new ElementException(field, \"NodeInputList field must be annotated with @\" + Input.getSimpleName() + \" or @\" + OptionalInput.getSimpleName());\n                    }\n                    if (isAssignableWithErasure(field, NodeSuccessorList)) {\n                        throw new ElementException(field, \"NodeSuccessorList field must be annotated with @\" + Successor.getSimpleName());","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java#L136-L172","documentation":"A @Successor field that is not a NodeSuccessorList must have a type assignable to Node. Successors are control-flow edges of the graph and can only point at nodes; a successor typed as an arbitrary class or interface has no meaning to the graph machinery. The NodeInfo processor verifies this with erased-type assignability and fails the build otherwise.","triggerScenarios":"!isAssignableWithErasure(field, Node) on a @Successor field in the non-list branch (GraphNodeVerifier.java:153-155). Example: '@Successor protected Exception edge;' or '@Successor protected SomeInterface next;' where neither extends Node.","commonSituations":"Annotating a data or reference field with @Successor by mistake instead of @Input; renaming/mistyping the successor's type; using a wrapper class instead of the node itself as successor.","solutions":["Change the field type to a Node subtype (e.g. FixedNode, AbstractBeginNode, ValueNode).","If the field is data or a value dependency, use @Input/@OptionalInput (and an interface/Node type) instead of @Successor.","If a list of control-flow targets is needed, use NodeSuccessorList with @Successor.","Rebuild to confirm."],"exampleFix":"// before\n@Successor\nprotected MyBlock next; // MyBlock does not extend Node\n\n// after\n@Successor\nprotected FixedWithNextNode next;","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember the annotation semantics: @Successor is control flow (Node types only), @Input is data flow.","Declare successors with concrete Node subtypes such as FixedWithNextNode or AbstractBeginNode."],"tags":["java","graalvm","annotation-processing","graal-node","control-flow","type-system","compile-time"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}