{"record":{"id":"d05309dd0294b902","repo":"neon-bindings/neon","slug":"expected-mut-cx-instead-of-a-channel-reference-mod","errorCode":null,"errorMessage":"Expected `&mut Cx` instead of a `Channel` reference.","messagePattern":"Expected `&mut Cx` instead of a `Channel` reference\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/export/function/mod.rs","lineNumber":205,"sourceCode":"\n// Checks if a _sync_ function has a context argument and if it is valid\n// * If the `context` attribute is included, must be at least one argument\n// * Inferred to be context if named `FunctionContext` or `Cx`\n// * Context argument must be a `&mut` reference\n// * First argument must not be `Channel`\n// * Must not be a `self` receiver\nfn check_context(opts: &meta::Meta, sig: &syn::Signature) -> syn::Result<bool> {\n    // Extract the first argument\n    let ty = match first_arg(opts, sig)? {\n        Some(arg) => arg,\n        None => return Ok(false),\n    };\n\n    // Extract the reference type\n    let ty = match &*ty.ty {\n        // Tried to use a borrowed Channel\n        syn::Type::Reference(ty) if !opts.context && is_channel_type(&ty.elem) => {\n            return Err(syn::Error::new(\n                ty.elem.span(),\n                \"Expected `&mut Cx` instead of a `Channel` reference.\",\n            ))\n        }\n\n        syn::Type::Reference(ty) => ty,\n\n        // Context needs to be a reference\n        _ if opts.context || is_context_type(&ty.ty) => {\n            return Err(syn::Error::new(\n                ty.ty.span(),\n                \"Context must be a `&mut` reference.\",\n            ))\n        }\n\n        // Hint that `Channel` should be swapped for `&mut Cx`\n        _ if is_channel_type(&ty.ty) => {\n            return Err(syn::Error::new(","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/export/function/mod.rs#L187-L223","documentation":"Compile-time error from Neon's `#[neon] fn` macro's context-type check. A function parameter was declared as a borrowed `&Channel` (or reference to Channel), but Neon requires the execution context parameter to be `&mut Cx`. Channels cannot be used as a borrowed context argument.","triggerScenarios":"Declaring a Neon exported function like `fn my_fn(mut cx: &Channel)` or taking `&Channel` as a parameter where the macro expects a context type — specifically when the parameter is a `Type::Reference` whose element `is_channel_type()` and no `#[context]`-style opts flag is set.","commonSituations":"Developers trying to pass a Channel to background tasks directly as an argument type, confusing `Channel` with `Cx`/`FunctionContext`, or copying signatures from async examples that spawn channels elsewhere.","solutions":["Change the parameter to a mutable context reference: `fn my_fn(mut cx: &mut Cx)` (or `FunctionContext`).","If you need a Channel for async work, create/obtain it inside the function from the context (`cx.channel()`), not as a parameter type.","Do not wrap `Channel` in a plain borrow; if a stored Channel is needed, take it as an owned/moved argument or via `JsFunction` arguments, not as the context slot."],"exampleFix":"// before\nfn my_fn(channel: &Channel) -> JsResult<JsUndefined> { ... }\n// after\nfn my_fn(mut cx: &mut FunctionContext) -> JsResult<JsUndefined> {\n    let channel = cx.channel();\n    ...\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Ensure the context parameter is a mutable reference, never a Channel reference:\nfn uses_valid_context(cx: &mut neon::context::FunctionContext) {}\n// Prefer `&mut Cx`/`&mut FunctionContext` for the first parameter; obtain channels via cx.channel().","tryCatchPattern":"// Compile-time error; pattern for CI gating:\n// if `cargo check` output contains \"Expected `&mut Cx` instead of a `Channel` reference.\"\n// then fail the build with a pointer to the offending fn signature.","preventionTips":["Never use `Channel` (borrowed or owned) in the context parameter position; use `&mut Cx` or `&mut FunctionContext`.","Get channels inside the function body with `cx.channel()`.","Keep exported function signatures consistent with Neon examples and run `cargo check` in CI."],"tags":["rust","neon","proc-macro","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"38960e4381d9ad13b551cdf2d261f609167c9bc2","analyzedAt":"2026-09-13T09:05:33.640Z","contentChangedAt":"2026-09-13T09:05:33.640Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}