neon-bindings/neon · error
Constructor methods cannot have a `self` receiver
Error message
Constructor methods cannot have a `self` receiver
What it means
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.
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.
Example fix
// before
#[neon]
impl Counter {
fn new(&self, initial: f64) -> JsResult<JsValue> { ... }
}
// after
#[neon]
impl Counter {
fn new(mut cx: FunctionContext, initial: f64) -> JsResult<JsValue> { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// Constructor signature lint
fn assert_constructor_has_no_receiver(fn_name: &str, params: &[&str]) -> Result<(), String> {
if fn_name == "new" && params.first().map(|p| p.ends_with("self")).unwrap_or(false) {
return Err("constructor `new` must not take self".into());
}
Ok(())
} Prevention
- 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) -> ...`.
When it happens
Trigger: Declaring a constructor as `fn new(&self) -> JsResult<...>`, `fn new(&mut self)`, or `fn new(self)` inside a `#[neon] impl` block.
Common situations: 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`.
Related errors
- in classes must take `self` by value, not `&self` or `&mut…
- Class methods must have a `self` receiver (`&self` or `&mut…
- 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/e82d383fb5075f35.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon-macros/src/class/mod.rs:590
let method_type = if matches!(meta.kind, meta::Kind::AsyncFn) {
"Async functions"
} else {
"Task methods"
};
return Err(syn::Error::new(
sig.span(),
format!(
"{} in classes must take `self` as their first parameter.",
method_type
),
));
}
}
// Check for self parameter in constructor
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",View on GitHub (pinned to 38960e4381)