napi-rs/napi-rs · error · Error
format!($msg, type_of!($env, $val)?)
Error message
format!($msg, type_of!($env, $val)?)
What it means
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.
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
Example fix
// before
addon.process(input.id); // input.id may be a string
// after
if (typeof input.id !== 'number') throw new TypeError('id must be a number');
addon.process(input.id); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof value !== 'string') throw new TypeError(`expected string, got ${typeof value}`); Type guard
const isString = (v) => typeof v === 'string';
Try / catch
try { addon.consume(value); } catch (e) { if (/type/i.test(e.message)) throw new TypeError(`bad argument: ${e.message}`); throw e; } Prevention
- 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
When it happens
Trigger: `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).
Common situations: 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.
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
- error_msg (format!($msg, value_type))
- InvalidArg
- Invalid value
- Value is none of these types
- < > on `External` is not the type of wrapped object
AI-assisted analysis of napi-rs/napi-rs@39bd1205e4 (2026-09-13).
Data as JSON: /api/errors/8270c88e68fc4faa.
Report an issue: GitHub.
Appendix: source
Thrown at crates/napi/src/error.rs:1748
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => Err($crate::Error::new($crate::Status::from(c), "".to_owned())),
}
}};
($code:expr, $($msg:tt)*) => {{
let c = $code;
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => Err($crate::Error::new($crate::Status::from(c), format!($($msg)*))),
}
}};
($code:expr, $msg:expr, $env:expr, $val:expr) => {{
let c = $code;
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => Err($crate::Error::new($crate::Status::from(c), format!($msg, $crate::type_of!($env, $val)?))),
}
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! check_status_and_type {
($code:expr, $env:ident, $val:ident, $msg:expr) => {{
let c = $code;
match c {
$crate::sys::Status::napi_ok => Ok(()),
_ => {
use $crate::js_values::JsValue;
let value_type = $crate::type_of!($env, $val)?;
let error_msg = match value_type {
ValueType::Function => {
let function_name = unsafe {
$crate::bindgen_prelude::Function::<View on GitHub (pinned to 39bd1205e4)