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

  1. Wrap the data with `Buffer.from(uint8Array)` / `Buffer.from(arrayBuffer)` before calling
  2. If you already have a Buffer, pass it directly — do not re-wrap into Uint8Array which would lose Buffer identity
  3. In cross-realm code, create the Buffer in the main Node realm
  4. 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

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


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)