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

  1. Add `self` as the first parameter of the method (by value).
  2. 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]`.
  3. 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

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


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)