denoland/deno · error · TypeError

source must be a TypedArray or a DataView

Error message

source must be a TypedArray or a DataView

What it means

Serializer#writeRawBytes(source) copies raw bytes into the V8 value stream and requires source to be a TypedArray or DataView; the isArrayBufferView guard throws a plain TypeError for anything else. It is mostly reached from custom Serializer subclasses building host-object encodings.

Source

Thrown at ext/node/polyfills/v8.ts:375

    return buf;
  }

  transferArrayBuffer(_id: number, _arrayBuffer: ArrayBuffer): void {
    op_v8_transfer_array_buffer(this[kHandle], _id, _arrayBuffer);
  }

  writeDouble(value: number): void {
    op_v8_write_double(this[kHandle], value);
  }

  writeHeader(): void {
    op_v8_write_header(this[kHandle]);
    this[kHeaderWritten] = true;
  }

  writeRawBytes(source: ArrayBufferView): void {
    if (!isArrayBufferView(source)) {
      throw new TypeError(
        "source must be a TypedArray or a DataView",
      );
    }
    op_v8_write_raw_bytes(this[kHandle], source);
  }

  writeUint32(value: number): void {
    op_v8_write_uint32(this[kHandle], value);
  }

  writeUint64(hi: number, lo: number): void {
    op_v8_write_uint64(this[kHandle], hi, lo);
  }

  // deno-lint-ignore no-explicit-any
  writeValue(value: any): void {
    op_v8_write_value(this[kHandle], value);
  }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass a view: writeRawBytes(Buffer.from(str, 'utf8')) or writeRawBytes(new Uint8Array(ab)).
  2. Convert collected arrays first: writeRawBytes(Uint8Array.from(parts.flat())).
  3. Annotate the parameter as ArrayBufferView so TypeScript rejects other inputs at the call site.

Example fix

// before
_writeHostObject(o) { this.writeRawBytes(o.hexString); } // string -> TypeError

// after
_writeHostObject(o) { this.writeRawBytes(Buffer.from(o.hexString, "hex")); }
Defensive patterns

Strategy: type-guard

Validate before calling

function toByteView(src) {
  if (ArrayBuffer.isView(src)) return src;
  if (src instanceof ArrayBuffer) return new Uint8Array(src);
  return Buffer.from(src); // strings, arrays of numbers
}

Type guard

const isView = (v) => ArrayBuffer.isView(v);

Prevention

When it happens

Trigger: A class extending v8.Serializer whose _writeHostObject (or manual protocol code) calls writeRawBytes('...'), writeRawBytes(new ArrayBuffer(8)), or writeRawBytes([1, 2, 3]).

Common situations: Porting serialization code where the byte-container type changed (string vs Buffer); interop layers accumulating chunks as arrays; feeding a detached/transferred view whose underlying buffer is gone.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/b8004202fbb7b2a5. Report an issue: GitHub.