neon-bindings/neon · error
in classes must take `self` as their first parameter.
Error message
{} in classes must take `self` as their first parameter. What it means
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.
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.
Example fix
// before
#[neon]
impl Foo {
async fn compute(x: f64) -> JsResult<JsNumber> { ... }
}
// after
#[neon]
impl Foo {
async fn compute(self, x: f64) -> JsResult<JsNumber> { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure methods exposed to JS carry a receiver
fn assert_method_has_self(params: &[&str]) -> bool {
params.first().map(|p| *p == "self").unwrap_or(false)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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
- Cannot combine async method with `#[neon(task)]` attribute
- in classes must take `self` by value, not `&self` or `&mut…
- class must be implemented for a type name
- The `neon::main` macro must only be used once
- Must settle a `neon::types::JsPromise` with…
AI-assisted analysis of neon-bindings/neon@38960e4381 (2026-09-13).
Data as JSON: /api/errors/59191c4c961661f8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon-macros/src/class/mod.rs:577
"This is required because async functions capture `self` in the Future, which must be `'static` for spawning."
} else {
"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."
};
return Err(syn::Error::new(
receiver.span(),
format!(
"{} in classes must take `self` by value, not `&self` or `&mut self`. {}",
method_type, reason
),
));
}
} else {
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 {View on GitHub (pinned to 38960e4381)