{"record":{"id":"5474b6d5cf42686c","repo":"denoland/deno","slug":"buffer-must-be-a-typedarray-or-a-dataview","errorCode":null,"errorMessage":"buffer must be a TypedArray or a DataView","messagePattern":"buffer must be a TypedArray or a DataView","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/v8.ts","lineNumber":318,"sourceCode":"    if (count === 0) return [];\n    return [`${count} instance(s) of ${name}`];\n  }\n  // Default format returns live object handles, which would require V8's\n  // `HeapProfiler::QueryObjects` (not exposed in rusty_v8). Returning an\n  // empty array keeps the signature sensible.\n  return [];\n}\n\n// deno-lint-ignore no-explicit-any\nfunction serialize(value: any) {\n  const ser = new DefaultSerializer();\n  ser.writeHeader();\n  ser.writeValue(value);\n  return ser.releaseBuffer();\n}\nfunction deserialize(buffer: Buffer | ArrayBufferView | DataView) {\n  if (!isArrayBufferView(buffer)) {\n    throw new TypeError(\n      \"buffer must be a TypedArray or a DataView\",\n    );\n  }\n  const der = new DefaultDeserializer(buffer);\n  der.readHeader();\n  return der.readValue();\n}\n\nconst kHandle = Symbol(\"kHandle\");\nconst kHeaderWritten = Symbol(\"kHeaderWritten\");\n\nclass Serializer {\n  [kHandle]: object;\n  [kHeaderWritten] = false;\n  constructor() {\n    this[kHandle] = op_v8_new_serializer(this);\n  }\n","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/v8.ts#L300-L336","documentation":"v8.deserialize(buffer) expects the serialized value's backing bytes as a TypedArray or DataView. The polyfill checks isArrayBufferView(buffer) and throws a plain TypeError otherwise, matching Node. A bare ArrayBuffer, a string, or null all fail because the deserializer needs the view's byteOffset and length.","triggerScenarios":"v8.deserialize(new ArrayBuffer(n)), v8.deserialize(someString), or v8.deserialize(null). A Node Buffer or any TypedArray/DataView passes.","commonSituations":"Storing v8.serialize() output and then transferring/postMessaging it so it arrives as a bare ArrayBuffer; reading a file or fetch body into an ArrayBuffer and forgetting to wrap; structured-clone round trips that strip the view.","solutions":["Wrap the buffer in a view: v8.deserialize(new Uint8Array(arrayBuffer)).","Use Buffer.from(data) (or Buffer.concat(chunks)) for network/file payloads before deserializing.","Type the parameter as Buffer | ArrayBufferView | DataView in your API so mistakes surface at compile time."],"exampleFix":"// before\nconst ab = await response.arrayBuffer(); // bare ArrayBuffer\nconst value = v8.deserialize(ab);        // TypeError\n\n// after\nconst value = v8.deserialize(new Uint8Array(await response.arrayBuffer()));","handlingStrategy":"type-guard","validationCode":"function asView(buf) {\n  return ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf);\n}\n// then always: v8.deserialize(asView(data))","typeGuard":"const isBufferView = (v) => ArrayBuffer.isView(v);","tryCatchPattern":null,"preventionTips":["Keep v8-serialized bytes in a Buffer/Uint8Array end to end.","After postMessage or file round trips, re-wrap with Buffer.from before deserializing.","Remember a bare ArrayBuffer is not accepted — only views over it."],"tags":["v8","serialization","typedarray","typeerror"],"backgroundTag":"buffer-type-validation","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}