neon-bindings/neon · error

Expected a context argument after `&self` when using…

Error message

Expected a context argument after `&self` when using `#[neon(context)]`. Add a parameter like `cx: &mut FunctionContext` or remove the `context` attribute.

What it means

Compile-time error from Neon's `#[neon]` class macro, raised by `first_arg` when `#[neon(context)]` forces context mode. The macro skips `&self` and looks for a second argument; when the method has no argument after `&self` and `opts.context` is set, it reports that a context parameter (like `cx: &mut FunctionContext`) is mandatory under the `context` attribute.

Solutions

  1. Add a context parameter after `&self`: `fn foo(&self, cx: &mut FunctionContext)` (or the appropriate `&mut Cx` variant).
  2. Remove the `#[neon(context)]` attribute from the method if a context is not needed.
  3. If the context requirement comes from a project-wide setting, either update all exported methods or disable that setting.

Example fix

// before
#[neon(context)]
fn size(&self) -> JsResult<JsNumber> {
    ...
}

// after
#[neon(context)]
fn size(&self, cx: &mut FunctionContext) -> JsResult<JsNumber> {
    ...
}
Defensive patterns

Strategy: validation

Validate before calling

// Under #[neon(context)], every &self method must declare a context parameter after &self.
fn validate_context_method(inputs: &[&str]) -> Result<(), String> {
    if inputs.len() < 2 {
        return Err("#[neon(context)] requires a context parameter after &self, e.g. cx: &mut FunctionContext".into());
    }
    Ok(())
}

Type guard

fn has_context_arg(inputs: &[String]) -> bool {
    inputs.get(1).map(|t| {
        t.starts_with("&mut FunctionContext") || t.starts_with("&mut Cx")
    }).unwrap_or(false)
}

Prevention

When it happens

Trigger: Annotating a `&self` method with `#[neon(context)]` (or building under a context-forced configuration) while the method signature has no parameter after `&self`, e.g. `fn size(&self) -> JsResult<...>` with `#[neon(context)]`.

Common situations: Adopting the `#[neon(context)]` attribute on existing zero-argument methods; enabling the context flag project-wide (e.g. via the neon `context` feature in Cargo.toml) without updating method signatures; forgetting that `&self` alone does not count as the context argument.

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/96689251ed8521cd. Report an issue: GitHub.

Appendix: source

Thrown at crates/neon-macros/src/class/mod.rs:481

            "Context is not available in async functions. Try a `Channel` instead.",
        )),

        _ => Ok(false),
    }
}

// Extract the first argument (after &self) from a method signature
fn first_arg<'a>(
    opts: &meta::Meta,
    sig: &'a syn::Signature,
) -> syn::Result<Option<&'a syn::PatType>> {
    // Extract the second argument (skip &self)
    let arg = match sig.inputs.iter().nth(1) {
        Some(arg) => arg,

        // If context was forced, error to let the user know the mistake
        None if opts.context => {
            return Err(syn::Error::new(
                sig.inputs.span(),
                "Expected a context argument after `&self` when using `#[neon(context)]`. Add a parameter like `cx: &mut FunctionContext` or remove the `context` attribute.",
            ))
        }

        None => return Ok(None),
    };

    // Expect a typed pattern; self receivers are not supported (but shouldn't appear here)
    match arg {
        syn::FnArg::Typed(ty) => Ok(Some(ty)),
        syn::FnArg::Receiver(arg) => Err(syn::Error::new(
            arg.span(),
            "Unexpected second receiver argument.",
        )),
    }
}

View on GitHub (pinned to 38960e4381)