{"record":{"id":"59191c4c961661f8","repo":"neon-bindings/neon","slug":"in-classes-must-take-self-as-their-first-parameter","errorCode":null,"errorMessage":"{} in classes must take `self` as their first parameter.","messagePattern":"(.+?) in classes must take `self` as their first parameter\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/class/mod.rs","lineNumber":577,"sourceCode":"                    \"This is required because async functions capture `self` in the Future, which must be `'static` for spawning.\"\n                } else {\n                    \"Since the instance is cloned before moving to the worker thread, taking `&self` would operate on a temporary reference to the clone, which is misleading.\"\n                };\n                return Err(syn::Error::new(\n                    receiver.span(),\n                    format!(\n                        \"{} in classes must take `self` by value, not `&self` or `&mut self`. {}\",\n                        method_type, reason\n                    ),\n                ));\n            }\n        } else {\n            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 {","sourceCodeStart":559,"sourceCodeEnd":595,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/class/mod.rs#L559-L595","documentation":"Async functions and `#[neon(task)]` methods must receive the class instance as their first parameter. The macro expects a `self` receiver (by value) on these methods so it can clone the instance and hand ownership to the spawned future or task; a method without one cannot be scheduled.","triggerScenarios":"Declaring `async fn work(x: f64)` or `#[neon(task)] fn run(x: f64)` with no `self` parameter at all inside a `#[neon] impl` block for a class.","commonSituations":"Writing helper functions inside the impl block and accidentally annotating them as async/task methods; refactoring away `self` when it appears unused; translating free functions into class methods without adding the receiver.","solutions":["Add `self` as the first parameter of the method (by value).","If the method genuinely doesn't need the instance, move it to a private free function or a plain associated fn not exposed via `#[neon]`.","If it should be a standalone task, define it as a separate type implementing the task pattern instead."],"exampleFix":"// before\n#[neon]\nimpl Foo {\n    async fn compute(x: f64) -> JsResult<JsNumber> { ... }\n}\n\n// after\n#[neon]\nimpl Foo {\n    async fn compute(self, x: f64) -> JsResult<JsNumber> { ... }\n}","handlingStrategy":"validation","validationCode":"// Ensure methods exposed to JS carry a receiver\nfn assert_method_has_self(params: &[&str]) -> bool {\n    params.first().map(|p| *p == \"self\").unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never expose plain helper functions (without self) via #[neon] method attributes.","Keep non-instance helpers as free functions or non-annotated associated fns.","Run `cargo check` after any signature refactor of #[neon] impl blocks."],"tags":["rust","neon","macros","async","missing-self"],"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"}