denoland/deno · error · NodeTypeError

ERR_INVALID_ARG_VALUE

ERR_INVALID_ARG_VALUE

Error message

The argument 'buffer' is empty and cannot be written. Received ${value}

What it means

In callback-style fs.read (ext/node/polyfills/_fs/_fs_read.ts), after argument normalization the zero-length fast path only fires when length === 0. If length is non-zero but the supplied buffer's byte length is 0, it throws ERR_INVALID_ARG_VALUE('buffer', buffer, 'is empty and cannot be written'). The read would have nowhere to put bytes.

Source

Thrown at ext/node/polyfills/_fs/_fs_read.ts:149

    validateInteger(offset, "offset", 0);
  }

  (length as number) |= 0;

  if (position == null) {
    position = -1;
  } else {
    validatePosition(position, "position", length as number);
  }

  if (length === 0) {
    return lazyProcess().default.nextTick(function tick() {
      callback!(null, 0, buffer);
    });
  }

  if (getByteLength(buffer as ArrayBufferView) === 0) {
    throw new ERR_INVALID_ARG_VALUE(
      "buffer",
      buffer,
      "is empty and cannot be written",
    );
  }

  validateOffsetLengthRead(
    offset,
    length,
    getByteLength(buffer as ArrayBufferView),
  );

  // BigInt avoids precision loss for positions > 2^53. -1n means current pos.
  const readPos = position != null && position >= 0
    ? BigInt(position as number | bigint)
    : -1n;
  PromisePrototypeThen(
    op_node_fs_read_deferred(

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Check the buffer length before reading: if (buf.length === 0) skip or allocate a real size
  2. Fix the size arithmetic that produced an empty buffer (e.g., remaining-bytes calculation)
  3. For 'read whatever is left', pass a properly sized buffer and let nread report the actual bytes

Example fix

// before
fs.read(fd, buf.subarray(0, remaining), 0, remaining, pos, cb); // remaining = 0

// after
if (remaining <= 0) return cb(null, 0, buf);
fs.read(fd, buf.subarray(0, remaining), 0, remaining, pos, cb);
Defensive patterns

Strategy: validation

Validate before calling

if (buffer.length === 0) {
  return callback(null, 0, buffer); // nothing to read into
}

Type guard

const hasCapacity = (buf) => buf != null && buf.byteLength > 0;

Prevention

When it happens

Trigger: fs.read(fd, Buffer.alloc(0), 0, 5, null, cb); fs.read(fd, new Uint8Array(0), { length: 1 }, cb); any call where an explicitly passed zero-length Buffer/TypedArray is combined with a positive length (explicit, or defaulted from a non-empty offset).

Common situations: Allocating a buffer from a computed size that rounds to 0 (e.g., fileSize - alreadyRead when the file is fully consumed); reusing a buffer that was subarray()'d to nothing; off-by-one length math.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/cffa60b12b1670af. Report an issue: GitHub.