neon-bindings/neon · error
Expected `&mut Cx` instead of `Channel`.
Error message
Expected `&mut Cx` instead of `Channel`.
What it means
Compile-time error from Neon's context check: a parameter in the context position was an owned `Channel` (by value, not a reference) where a mutable context reference is required. Neon explicitly hints that `Channel` should be swapped for `&mut Cx`.
Solutions
- Replace the `Channel` parameter with `mut cx: &mut Cx` / `&mut FunctionContext`.
- If a Channel is needed for background work, obtain it inside the function via `cx.channel()`.
- If you need a Channel as data, accept it through a different mechanism (e.g. stored in a struct passed as an argument), not in the context position.
Example fix
// before
fn my_fn(channel: Channel) -> JsResult<JsUndefined> { ... }
// after
fn my_fn(mut cx: &mut FunctionContext) -> JsResult<JsUndefined> {
let channel = cx.channel();
...
} Defensive patterns
Strategy: type-guard
Type guard
// Ensure no parameter in the context position is an owned Channel:
// bad: fn f(ch: Channel)
// good: fn f(mut cx: &mut FunctionContext)
fn valid_context(cx: &mut neon::context::FunctionContext) {} Try / catch
// Compile-time error; pattern for CI gating: // if `cargo check` output contains "Expected `&mut Cx` instead of `Channel`." // then replace the Channel parameter with a context reference.
Prevention
- Treat the first context-slot parameter as reserved for `&mut Cx`/`&mut FunctionContext`.
- Create Channels inside the function via `cx.channel()` instead of taking them as parameters.
- Review Neon async examples for correct Channel usage patterns.
When it happens
Trigger: Declaring `fn my_fn(channel: Channel)` — an un-borrowed `Channel` type in the parameter list that `is_channel_type()` matches, in the context slot of an exported function.
Common situations: Developers copying `Channel` from async/threading examples into the context parameter position, or trying to receive a Channel as the first argument of an exported function instead of the context.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Context must be a `&mut` reference.
- Expected `&mut Cx` instead of a `Channel` reference.
- Context must be a `&mut` reference.
- Expected an owned `Channel` instead of a context reference.
- Context is not available in async functions. Try a…
AI-assisted analysis of neon-bindings/neon@38960e4381 (2026-09-13).
Data as JSON: /api/errors/660c64c721a4a1a4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon-macros/src/export/function/mod.rs:224
ty.elem.span(),
"Expected `&mut Cx` instead of a `Channel` reference.",
))
}
syn::Type::Reference(ty) => ty,
// Context needs to be a reference
_ if opts.context || is_context_type(&ty.ty) => {
return Err(syn::Error::new(
ty.ty.span(),
"Context must be a `&mut` reference.",
))
}
// Hint that `Channel` should be swapped for `&mut Cx`
_ if is_channel_type(&ty.ty) => {
return Err(syn::Error::new(
ty.ty.span(),
"Expected `&mut Cx` instead of `Channel`.",
))
}
_ => return Ok(false),
};
// Not a forced or inferred context
if !opts.context && !is_context_type(&ty.elem) {
return Ok(false);
}
// Context argument must be mutable
if ty.mutability.is_none() {
return Err(syn::Error::new(ty.span(), "Must be a `&mut` reference."));
}
// All tests passed!View on GitHub (pinned to 38960e4381)