{"record":{"id":"2a9cffebc1a07624","repo":"napi-rs/napi-rs","slug":"expected-a-buffer-value","errorCode":null,"errorMessage":"Expected a Buffer value","messagePattern":"Expected a Buffer value","errorType":"validation","errorClass":"InvalidArg","httpStatus":null,"severity":"error","filePath":"crates/napi/src/bindgen_runtime/js_values/buffer.rs","lineNumber":372,"sourceCode":"impl TypeName for BufferSlice<'_> {\n  fn type_name() -> &'static str {\n    \"Buffer\"\n  }\n\n  fn value_type() -> ValueType {\n    ValueType::Object\n  }\n}\n\nimpl ValidateNapiValue for BufferSlice<'_> {\n  unsafe fn validate(env: sys::napi_env, napi_val: sys::napi_value) -> Result<sys::napi_value> {\n    let mut is_buffer = false;\n    check_status!(\n      unsafe { sys::napi_is_buffer(env, napi_val, &mut is_buffer) },\n      \"Failed to validate napi buffer\"\n    )?;\n    if !is_buffer {\n      return Err(Error::new(\n        Status::InvalidArg,\n        \"Expected a Buffer value\".to_owned(),\n      ));\n    }\n    Ok(ptr::null_mut())\n  }\n}\n\nimpl AsRef<[u8]> for BufferSlice<'_> {\n  fn as_ref(&self) -> &[u8] {\n    self.inner\n  }\n}\n\nimpl Deref for BufferSlice<'_> {\n  type Target = [u8];\n\n  fn deref(&self) -> &Self::Target {","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/napi-rs/napi-rs/blob/39bd1205e480a453a2da2601a760bde5a71ed016/crates/napi/src/bindgen_runtime/js_values/buffer.rs#L354-L390","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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`"],"exampleFix":"// before\nconst view = new Uint8Array(fileBytes);\nnativeHash(view);\n// after\nnativeHash(Buffer.from(fileBytes));","handlingStrategy":"type-guard","validationCode":"function assertBuffer(v) { if (!Buffer.isBuffer(v)) throw new TypeError('Expected a Buffer value, got ' + typeof v); }","typeGuard":"function isBuffer(v) { return Buffer.isBuffer(v); }","tryCatchPattern":"try {\n  nativeFn(maybeBuffer);\n} catch (e) {\n  if (e.code === 'InvalidArg' && e.message.includes('Expected a Buffer value')) {\n    nativeFn(Buffer.from(maybeBuffer));\n  } else throw e;\n}","preventionTips":["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"],"tags":["buffer","napi-rs","argument-validation"],"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"}