{"record":{"id":"e82d383fb5075f35","repo":"neon-bindings/neon","slug":"constructor-methods-cannot-have-a-self-receiver","errorCode":null,"errorMessage":"Constructor methods cannot have a `self` receiver","messagePattern":"Constructor methods cannot have a `self` receiver","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/class/mod.rs","lineNumber":590,"sourceCode":"            let method_type = if matches!(meta.kind, meta::Kind::AsyncFn) {\n                \"Async functions\"\n            } else {\n                \"Task methods\"\n            };\n            return Err(syn::Error::new(\n                sig.span(),\n                format!(\n                    \"{} in classes must take `self` as their first parameter.\",\n                    method_type\n                ),\n            ));\n        }\n    }\n\n    // Check for self parameter in constructor\n    if sig.ident == \"new\" {\n        if let Some(syn::FnArg::Receiver(_)) = sig.inputs.first() {\n            return Err(syn::Error::new(\n                sig.ident.span(),\n                \"Constructor methods cannot have a `self` receiver\",\n            ));\n        }\n    } else {\n        fn starts_with_self_arg(sig: &syn::Signature) -> bool {\n            if let Some(first_arg) = sig.inputs.first() {\n                matches!(first_arg, syn::FnArg::Receiver(_))\n            } else {\n                false\n            }\n        }\n\n        // Check for self parameter in non-constructor methods\n        if !starts_with_self_arg(sig) {\n            return Err(syn::Error::new(\n                sig.ident.span(),\n                \"Class methods must have a `self` receiver (`&self` or `&mut self`) as their first parameter\",","sourceCodeStart":572,"sourceCodeEnd":608,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/class/mod.rs#L572-L608","documentation":"The method named `new` acts as the class constructor, mapping to JavaScript's `new Foo(...)`. Constructors run before any instance exists, so they must not take a `self` receiver; `fn new(&self)` or `fn new(self)` is rejected by the macro.","triggerScenarios":"Declaring a constructor as `fn new(&self) -> JsResult<...>`, `fn new(&mut self)`, or `fn new(self)` inside a `#[neon] impl` block.","commonSituations":"Writing a conventional Rust builder-style `new(&self)`; converting a normal method into a constructor by renaming it to `new` without dropping the receiver; porting code from other Rust patterns where `new` takes `&self`.","solutions":["Remove the receiver entirely: declare `fn new(...args) -> JsResult<...>` (optionally with `cx: &mut FunctionContext`).","If the method legitimately needs an existing instance, rename it to something other than `new` so it is treated as a regular method."],"exampleFix":"// before\n#[neon]\nimpl Counter {\n    fn new(&self, initial: f64) -> JsResult<JsValue> { ... }\n}\n\n// after\n#[neon]\nimpl Counter {\n    fn new(mut cx: FunctionContext, initial: f64) -> JsResult<JsValue> { ... }\n}","handlingStrategy":"validation","validationCode":"// Constructor signature lint\nfn assert_constructor_has_no_receiver(fn_name: &str, params: &[&str]) -> Result<(), String> {\n    if fn_name == \"new\" && params.first().map(|p| p.ends_with(\"self\")).unwrap_or(false) {\n        return Err(\"constructor `new` must not take self\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In neon, `fn new(...)` is always the constructor: never give it a receiver.","If you need instance access, that logic belongs in a differently-named method.","Follow the neon docs' constructor template: `fn new(mut cx: FunctionContext) -> ...`."],"tags":["rust","neon","macros","constructor","self-receiver"],"backgroundTag":"invalid-constructor-argument","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"}