{"record":{"id":"c69f6c955720b4b8","repo":"neon-bindings/neon","slug":"class-methods-must-have-a-self-receiver-self-or-mut-self-as","errorCode":null,"errorMessage":"Class methods must have a `self` receiver (`&self` or `&mut self`) as their first parameter","messagePattern":"Class methods must have a `self` receiver \\(`&self` or `&mut self`\\) as their first parameter","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/class/mod.rs","lineNumber":606,"sourceCode":"    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\",\n            ));\n        }\n    }\n\n    Ok(())\n}\n\n// Check if a method has a `this` parameter (adapted from export function)\n// For methods: &self is 1st, context is 2nd (optional), this is 3rd (or 2nd if no context)\nfn check_this(opts: &meta::Meta, sig: &syn::Signature, has_context: bool) -> bool {\n    static THIS: &str = \"this\";\n\n    // Forced `this` argument\n    if opts.this {\n        return true;\n    }","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/class/mod.rs#L588-L624","documentation":"Every non-constructor method in a neon class must take the instance as its first parameter via a `self` receiver (`&self`, `&mut self`, or `self`). The macro needs the receiver to access and expose the underlying Rust object from JavaScript; a method without one has no instance to operate on.","triggerScenarios":"Declaring any regular class method like `fn get(&self)`... actually `fn get()` / `fn set(value: f64)` with no `self` parameter in a `#[neon] impl` block (constructors named `new` are exempt).","commonSituations":"Writing static-style helper functions inside the impl block and exposing them as methods; accidentally deleting the receiver during refactoring; translating JS static methods into neon class methods without realizing all class methods are instance methods.","solutions":["Add a receiver as the first parameter, typically `&self` (or `&mut self` for mutation).","If the function doesn't need the instance, move it outside the impl block or mark it as a standalone function rather than a class method.","If a JS static method is intended, note that neon class methods are instance-bound; restructure accordingly."],"exampleFix":"// before\n#[neon]\nimpl Counter {\n    fn get() -> JsResult<JsNumber> { ... }\n}\n\n// after\n#[neon]\nimpl Counter {\n    fn get(&self) -> JsResult<JsNumber> { ... }\n}","handlingStrategy":"validation","validationCode":"// All exposed class methods need a receiver\nfn assert_class_method(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(\"class methods must take self as first parameter\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Every non-`new` method in a #[neon] impl block starts with `&self`, `&mut self`, or `self`.","Move stateless helpers outside the impl block or into a separate module.","Neon has no static class methods — don't try to emulate them inside the impl block."],"tags":["rust","neon","macros","self-receiver","method-signature"],"backgroundTag":"missing-required-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"}