{"record":{"id":"f35926547c070ec2","repo":"neon-bindings/neon","slug":"must-be-a-mut-reference-mod","errorCode":null,"errorMessage":"Must be a `&mut` reference.","messagePattern":"Must be a `&mut` reference\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/export/function/mod.rs","lineNumber":239,"sourceCode":"        // Hint that `Channel` should be swapped for `&mut Cx`\n        _ if is_channel_type(&ty.ty) => {\n            return Err(syn::Error::new(\n                ty.ty.span(),\n                \"Expected `&mut Cx` instead of `Channel`.\",\n            ))\n        }\n\n        _ => return Ok(false),\n    };\n\n    // Not a forced or inferred context\n    if !opts.context && !is_context_type(&ty.elem) {\n        return Ok(false);\n    }\n\n    // Context argument must be mutable\n    if ty.mutability.is_none() {\n        return Err(syn::Error::new(ty.span(), \"Must be a `&mut` reference.\"));\n    }\n\n    // All tests passed!\n    Ok(true)\n}\n\n// Checks if a _async_ function has a Channel argument and if it is valid\n// * If the `context` attribute is included, must be at least one argument\n// * Inferred to be channel if named `Channel`\n// * Channel argument must not be a reference\n// * First argument must not be `FunctionContext` or `Cx`\n// * Must not be a `self` receiver\nfn check_channel(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    };","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/export/function/mod.rs#L221-L257","documentation":"This compile-time error comes from Neon's `#[neon::export]` macro when a function parameter accepts a context type (`&Cx`/`&mut Cx`-like). The macro's `check_context` validation requires that a context argument be taken by mutable reference (`&mut Cx`). An immutable reference cannot support the interior mutability that Neon's context machinery relies on, so the macro rejects the signature.","triggerScenarios":"Declaring an exported fn (or a context-marked parameter, e.g. `#[context]` or forced `context` option) whose context parameter is spelled `&Cx` or `&CxContext` instead of `&mut Cx`. Detected in `check_context` when `ty.mutability.is_none()`.","commonSituations":"Copy-pasting a non-export helper signature into an `#[neon::export]` fn; habitually writing `&Cx` because Rust often prefers shared references; upgrading to Neon's new export API after previously using `ModuleContext` arguments.","solutions":["Change the context parameter to a mutable reference: `fn f(cx: &mut Cx)` instead of `cx: &Cx`.","If the parameter is not actually a context type, rename/retype it so the macro does not interpret it as one.","If the function does not need context, remove the context parameter (and any `context` attribute) entirely."],"exampleFix":"// before\n#[neon::export]\nfn add1(cx: &Cx, n: f64) -> f64 { n + 1.0 }\n\n// after\n#[neon::export]\nfn add1(cx: &mut Cx, n: f64) -> f64 { n + 1.0 }","handlingStrategy":"validation","validationCode":"// Compile-time guard: assert the export signature takes the context by &mut\nfn assert_mut_context(cx: &mut neon::context::CxContext) {}\n// use `assert_mut_context(cx);` inside the export fn; the signature itself\n// (`&mut CxContext`) is validated by the macro at compile time.","typeGuard":"fn is_mut_ref<T>(_: &mut T) -> bool { true } // prefer `&mut Cx` in every #[neon::export] signature","tryCatchPattern":null,"preventionTips":["Always write `&mut Cx` (never `&Cx`) for context parameters in exported functions.","Remember the mnemonic: context = &mut reference, channel = owned value.","Rely on `cargo check` after editing export signatures — these errors are compile-time."],"tags":["rust","neon","compile-time","macro","context-argument"],"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"}