napi-rs/napi-rs · error · InvalidArg
Expected a Buffer value
Error message
Expected a Buffer value
What it means
This InvalidArg error is raised by `ValidateNapiValue::validate` for `BufferSlice<'_>` in napi-rs. It fires during argument validation when `napi_is_buffer` reports the JS value is not a Node Buffer. BufferSlice gives Rust a zero-copy view of a Node Buffer's memory, so only genuine Buffer instances qualify.
Solutions
- Wrap the data with `Buffer.from(uint8Array)` / `Buffer.from(arrayBuffer)` before calling
- If you already have a Buffer, pass it directly — do not re-wrap into Uint8Array which would lose Buffer identity
- In cross-realm code, create the Buffer in the main Node realm
- Check the generated `.d.ts`: the parameter type is `Buffer`, not `Uint8Array`
Example fix
// before const view = new Uint8Array(fileBytes); nativeHash(view); // after nativeHash(Buffer.from(fileBytes));
Defensive patterns
Strategy: type-guard
Validate before calling
function assertBuffer(v) { if (!Buffer.isBuffer(v)) throw new TypeError('Expected a Buffer value, got ' + typeof v); } Type guard
function isBuffer(v) { return Buffer.isBuffer(v); } Try / catch
try {
nativeFn(maybeBuffer);
} catch (e) {
if (e.code === 'InvalidArg' && e.message.includes('Expected a Buffer value')) {
nativeFn(Buffer.from(maybeBuffer));
} else throw e;
} Prevention
- Use Buffer.isBuffer() at API boundaries before passing binary data to napi functions
- Do not assume every Uint8Array is a Buffer — only Buffer instances pass napi_is_buffer
- When data crosses realms (vm, workers), reconstruct the Buffer in the main realm
When it happens
Trigger: Passing a Uint8Array that is not a Buffer, a plain Array, an ArrayBuffer, a string, or null/undefined to a `#[napi]` function parameter typed as `BufferSlice`. Note: a Node Buffer IS a Uint8Array, but the reverse does not hold — `new Uint8Array()` will fail this check.
Common situations: Constructing views with `new Uint8Array(x)` instead of `Buffer.from(x)`; passing ArrayBuffer from fetch/Deno code; cross-realm Buffers (vm contexts, jsdom) that may fail `napi_is_buffer`; calling from browsers or runtimes without Node Buffers.
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
- Share the same data between different buffers is not…
- InvalidArg
- InvalidArg
- Expected a Date object
- InvalidArg
AI-assisted analysis of napi-rs/napi-rs@39bd1205e4 (2026-09-13).
Data as JSON: /api/errors/2a9cffebc1a07624.
Report an issue: GitHub.
Appendix: source
Thrown at crates/napi/src/bindgen_runtime/js_values/buffer.rs:372
impl TypeName for BufferSlice<'_> {
fn type_name() -> &'static str {
"Buffer"
}
fn value_type() -> ValueType {
ValueType::Object
}
}
impl ValidateNapiValue for BufferSlice<'_> {
unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {
let mut is_buffer = false;
check_status!(
unsafe { sys::napi_is_buffer(env, napi_val, &mut is_buffer) },
"Failed to validate napi buffer"
)?;
if !is_buffer {
return Err(Error::new(
Status::InvalidArg,
"Expected a Buffer value".to_owned(),
));
}
Ok(ptr::null_mut())
}
}
impl AsRef<[u8]> for BufferSlice<'_> {
fn as_ref(&self) -> &[u8] {
self.inner
}
}
impl Deref for BufferSlice<'_> {
type Target = [u8];
fn deref(&self) -> &Self::Target {View on GitHub (pinned to 39bd1205e4)