{"record":{"id":"18b1acf9db69c52e","repo":"neon-bindings/neon","slug":"must-be-a-mut-reference","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/class/mod.rs","lineNumber":426,"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                \"Unexpected `Channel` in sync method. Use `&mut FunctionContext` for sync methods, or `Channel` in async/task methods.\",\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// Check if an async method has a Channel argument (adapted from export function)\nfn check_channel(opts: &meta::Meta, sig: &syn::Signature) -> syn::Result<bool> {\n    // Extract the first argument (after &self)\n    let ty = match first_arg(opts, sig)? {\n        Some(arg) => arg,\n        None => return Ok(false),\n    };\n\n    // Check the type\n    match &*ty.ty {\n        // Provided `&mut Channel` instead of `Channel`\n        syn::Type::Reference(ty) if opts.context || is_channel_type(&ty.elem) => {","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/class/mod.rs#L408-L444","documentation":"A neon class method or exported function declared its context parameter as an immutable reference (e.g. `&Cx`, `&FunctionContext`). Contexts provide interior-mutable access to the JS runtime, so neon requires them to be `&mut` references. The macro checks mutability of the reference and fails compilation if it is missing.","triggerScenarios":"Declaring the context parameter as `&Cx`, `&FunctionContext`, `&'a mut`-less borrowed context, or any reference form where `mut` is absent, while the type is recognized as a context (or `#[neon(context)]` forces it).","commonSituations":"Writing idiomatic shared-reference style `&Cx` parameters; linters or manual refactors removing `mut`; porting code from libraries where contexts are borrowed immutably.","solutions":["Add `mut` to the reference: `&Cx` -> `&mut Cx`, `&FunctionContext` -> `&mut FunctionContext`.","If the surrounding code requires an immutable borrow, restructure so the context is only held where a `&mut` borrow is allowed (e.g. drop other borrows of the same data).","If the parameter is not actually a context, rename the type or remove the `context` attribute forcing it to be one.","Re-run the build after the fix — this error is purely about the missing `mut` token in the signature."],"exampleFix":"// before\nfn get_count(cx: &Cx) -> JsResult<JsNumber> { ... }\n\n// after\nfn get_count(cx: &mut Cx) -> JsResult<JsNumber> { ... }","handlingStrategy":"type-guard","validationCode":"// Guard: context reference must be mutable\nfn validate_mut_context(ty: &str) -> Result<(), String> {\n    if (ty.contains(\"Cx\") || ty.contains(\"FunctionContext\")) && ty.starts_with(\"&\") && !ty.starts_with(\"&mut \") {\n        return Err(format!(\"`{}` must be `&mut` reference\", ty));\n    }\n    Ok(())\n}","typeGuard":"fn is_mut_context_ref(ty: &syn::Type) -> bool {\n    matches!(ty, syn::Type::Reference(r) if r.mutability.is_some()\n        && [\"Cx\", \"FunctionContext\"].iter().any(|c| type_name(&r.elem).contains(c)))\n}","tryCatchPattern":null,"preventionTips":["Treat every neon context parameter as `&mut` by default","Do not run lints/fixes that strip `mut` from context references","Structure code so no conflicting immutable borrows force you to drop `mut`","Compile early and often — this is a one-token fix caught by the macro"],"tags":["rust","neon","compile-time","macro","mutability"],"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"}