{"record":{"id":"78dfe0ecd15410f4","repo":"oracle/graal","slug":"successor-list-field-must-not-be-final","errorCode":null,"errorMessage":"Successor list field must not be final","messagePattern":"Successor list field must not be final","errorType":"validation","errorClass":"ElementException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java","lineNumber":147,"sourceCode":"                        }\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)) {\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\")) {","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java#L129-L165","documentation":"A control-flow successor field typed NodeSuccessorList and annotated @Successor must not be final. Successor lists are rewritten whenever the control-flow graph is transformed (e.g. block reordering, node deletion), so the field must remain reassignable. The NodeInfo processor enforces this invariant at annotation-processing time.","triggerScenarios":"modifiers.contains(FINAL) on a @Successor field whose erased type is assignable to NodeSuccessorList (GraphNodeVerifier.java:146-148). Example: '@Successor protected final NodeSuccessor<FixedNode> successors;'.","commonSituations":"New control-flow nodes (FixedWithNext successors, branching nodes) written with immutable-field style; applying 'effectively final' refactors; porting node code between Graal versions.","solutions":["Remove final from the NodeSuccessorList field.","Initialize the list in the constructor (new NodeSuccessorList<>(this, ...)).","Keep visibility protected or package-private.","Rebuild to confirm."],"exampleFix":"// before\n@Successor\nprotected final NodeSuccessorList<FixedNode> nexts;\n\n// after\n@Successor\nprotected NodeSuccessorList<FixedNode> nexts;","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat successor lists as runtime-mutated state: never final.","Initialize NodeSuccessorList fields in the constructor.","Use existing fixed/branching nodes as templates for control-flow fields."],"tags":["java","graalvm","annotation-processing","graal-node","control-flow","compile-time"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}