neon-bindings/neon · error
Class methods must have a `self` receiver (`&self` or `&mut…
Error message
Class methods must have a `self` receiver (`&self` or `&mut self`) as their first parameter
What it means
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.
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.
Example fix
// before
#[neon]
impl Counter {
fn get() -> JsResult<JsNumber> { ... }
}
// after
#[neon]
impl Counter {
fn get(&self) -> JsResult<JsNumber> { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// All exposed class methods need a receiver
fn assert_class_method(fn_name: &str, params: &[&str]) -> Result<(), String> {
if fn_name != "new" && !params.first().map(|p| p.ends_with("self")).unwrap_or(false) {
return Err("class methods must take self as first parameter".into());
}
Ok(())
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- in classes must take `self` by value, not `&self` or `&mut…
- Constructor methods cannot have a `self` receiver
- Exported functions cannot receive `self`.
- class must be implemented for a type name
- The `neon::main` macro must only be used once
AI-assisted analysis of neon-bindings/neon@38960e4381 (2026-09-13).
Data as JSON: /api/errors/c69f6c955720b4b8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon-macros/src/class/mod.rs:606
if sig.ident == "new" {
if let Some(syn::FnArg::Receiver(_)) = sig.inputs.first() {
return Err(syn::Error::new(
sig.ident.span(),
"Constructor methods cannot have a `self` receiver",
));
}
} else {
fn starts_with_self_arg(sig: &syn::Signature) -> bool {
if let Some(first_arg) = sig.inputs.first() {
matches!(first_arg, syn::FnArg::Receiver(_))
} else {
false
}
}
// Check for self parameter in non-constructor methods
if !starts_with_self_arg(sig) {
return Err(syn::Error::new(
sig.ident.span(),
"Class methods must have a `self` receiver (`&self` or `&mut self`) as their first parameter",
));
}
}
Ok(())
}
// Check if a method has a `this` parameter (adapted from export function)
// For methods: &self is 1st, context is 2nd (optional), this is 3rd (or 2nd if no context)
fn check_this(opts: &meta::Meta, sig: &syn::Signature, has_context: bool) -> bool {
static THIS: &str = "this";
// Forced `this` argument
if opts.this {
return true;
}View on GitHub (pinned to 38960e4381)