{"record":{"id":"8274b0d736b474a4","repo":"neon-bindings/neon","slug":"only-one-finalize-method-is-allowed-in-a-class","errorCode":null,"errorMessage":"Only one `finalize` method is allowed in a class.","messagePattern":"Only one `finalize` method is allowed in a class\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/class/mod.rs","lineNumber":798,"sourceCode":"\n    for item in items {\n        match item {\n            syn::ImplItem::Const(c) => consts.push(c),\n            syn::ImplItem::Fn(f) => {\n                // Check if the function is a constructor\n                if f.sig.ident == \"new\" {\n                    if constructor.is_some() {\n                        let span = syn::spanned::Spanned::span(&f);\n                        let msg = \"Only one `new` constructor is allowed in a class.\";\n                        return Err(syn::Error::new(span, msg));\n                    }\n                    constructor = Some(f);\n                    continue; // Skip adding to fns\n                } else if f.sig.ident == \"finalize\" {\n                    if has_finalizer {\n                        let span = syn::spanned::Spanned::span(&f);\n                        let msg = \"Only one `finalize` method is allowed in a class.\";\n                        return Err(syn::Error::new(span, msg));\n                    }\n                    has_finalizer = true;\n                    continue; // Skip adding to fns\n                }\n                fns.push(f)\n            }\n            _ => {\n                let span = syn::spanned::Spanned::span(&item);\n                let msg = \"`neon::class` can only contain `const` and `fn` items.\";\n                return Err(syn::Error::new(span, msg));\n            }\n        }\n    }\n\n    Ok(ClassItems {\n        consts,\n        fns,\n        constructor,","sourceCodeStart":780,"sourceCodeEnd":816,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/class/mod.rs#L780-L816","documentation":"The neon #[class] macro detects duplicate `finalize` methods when grouping class items. `finalize` implements Drop for the exported class, so at most one can exist; a second triggers this compile-time error at the span of the offending method.","triggerScenarios":"Declaring two `fn finalize(self)` (or similar finalizer-named) methods inside a single `#[neon] impl` block of a class annotated with #[class].","commonSituations":"Refactoring that leaves an old finalizer in place while adding a new one; merge conflicts that keep both variants; copy-pasting a finalize method between impl blocks without removing the original; an associated fn accidentally named `finalize`.","solutions":["Delete or rename one of the duplicate `finalize` methods so only one remains per class","Merge the body of the two finalize methods into a single implementation","If the second method is unrelated logic, rename it (e.g. `cleanup`) so the macro no longer treats it as a finalizer"],"exampleFix":"// before\nimpl_finalize!(Greet);\nimpl Class for Greet {\n    fn finalize<'a>(&mut self, cx: &'a mut TaskContext<'a>) {}\n    fn finalize<'a>(&mut self, cx: &'a mut TaskContext<'a>) {} // duplicate\n}\n// after\nimpl Class for Greet {\n    fn finalize<'a>(&mut self, cx: &'a mut TaskContext<'a>) {\n        // single merged finalizer body\n    }\n}","handlingStrategy":"validation","validationCode":"// before compiling, ensure a single finalize per class impl\nfn validate_single_finalize(items: &[&str]) -> Result<(), String> {\n    let count = items.iter().filter(|i| i.trim().starts_with(\"fn finalize\")).count();\n    if count > 1 { Err(format!(\"{count} finalize methods found; only one allowed\")) } else { Ok(()) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep at most one `finalize` method per exported class","Search the impl block for `fn finalize` before adding a new one","Merge cleanup logic into the existing finalizer instead of adding another"],"tags":["rust","proc-macro","neon","duplicate-method","compile-time"],"backgroundTag":"internal-invariant-violation","analyzedSha":"38960e4381d9ad13b551cdf2d261f609167c9bc2","analyzedAt":"2026-09-13T09:05:33.640Z","contentChangedAt":"2026-09-13T09:05:33.640Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}