{"record":{"id":"8270c88e68fc4faa","repo":"napi-rs/napi-rs","slug":"format-msg-type-of-env-val","errorCode":null,"errorMessage":"format!($msg, type_of!($env, $val)?)","messagePattern":"format!\\(\\$msg, type_of!\\(\\$env, \\$val\\)\\?\\)","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/napi/src/error.rs","lineNumber":1748,"sourceCode":"    match c {\n      $crate::sys::Status::napi_ok => Ok(()),\n      _ => Err($crate::Error::new($crate::Status::from(c), \"\".to_owned())),\n    }\n  }};\n\n  ($code:expr, $($msg:tt)*) => {{\n    let c = $code;\n    match c {\n      $crate::sys::Status::napi_ok => Ok(()),\n      _ => Err($crate::Error::new($crate::Status::from(c), format!($($msg)*))),\n    }\n  }};\n\n  ($code:expr, $msg:expr, $env:expr, $val:expr) => {{\n    let c = $code;\n    match c {\n      $crate::sys::Status::napi_ok => Ok(()),\n      _ => Err($crate::Error::new($crate::Status::from(c), format!($msg, $crate::type_of!($env, $val)?))),\n    }\n  }};\n}\n\n#[doc(hidden)]\n#[macro_export]\nmacro_rules! check_status_and_type {\n  ($code:expr, $env:ident, $val:ident, $msg:expr) => {{\n    let c = $code;\n    match c {\n      $crate::sys::Status::napi_ok => Ok(()),\n      _ => {\n        use $crate::js_values::JsValue;\n        let value_type = $crate::type_of!($env, $val)?;\n        let error_msg = match value_type {\n          ValueType::Function => {\n            let function_name = unsafe {\n              $crate::bindgen_prelude::Function::<","sourceCodeStart":1730,"sourceCodeEnd":1766,"githubUrl":"https://github.com/napi-rs/napi-rs/blob/39bd1205e480a453a2da2601a760bde5a71ed016/crates/napi/src/error.rs#L1730-L1766","documentation":"This is the type-describing form of `check_status!` (crates/napi/src/error.rs:1748): `check_status!(code, msg, env, val)`. On a non-ok status it calls `type_of!(env, val)` to get the JS value's type name and interpolates it into the message. The error therefore tells you the Node-API call failed on a JS value of an unexpected type — typically an argument type mismatch.","triggerScenarios":"`check_status!(code, \"expected ... got {}\", env, val)` where the wrapped Node-API call fails because `val` is not of the type the native code requires (e.g. a string passed where an object or function is expected).","commonSituations":"Calling addon functions from JavaScript with wrong-typed arguments, refactors that changed a function signature on the JS side while native code still expects the old type, or dynamic values (from JSON.parse) reaching typed native parameters.","solutions":["Read the error message to see the actual JS type of the offending value","Validate/coerce the argument in JS before passing it to the addon (Number(), String(), typeof check)","Align the JS call site with the native function's expected parameter type"],"exampleFix":"// before\naddon.process(input.id); // input.id may be a string\n// after\nif (typeof input.id !== 'number') throw new TypeError('id must be a number');\naddon.process(input.id);","handlingStrategy":"type-guard","validationCode":"if (typeof value !== 'string') throw new TypeError(`expected string, got ${typeof value}`);","typeGuard":"const isString = (v) => typeof v === 'string';","tryCatchPattern":"try { addon.consume(value); } catch (e) { if (/type/i.test(e.message)) throw new TypeError(`bad argument: ${e.message}`); throw e; }","preventionTips":["typeof-check every argument crossing the JS/native boundary","Avoid passing values from JSON.parse directly into typed native functions","Keep TS types for the addon strict so type errors are caught at compile time"],"tags":["napi","native-addon","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"39bd1205e480a453a2da2601a760bde5a71ed016","analyzedAt":"2026-09-13T20:31:47.814Z","contentChangedAt":"2026-09-13T20:31:47.814Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}