denoland/deno · error · NodeError

ERR_METHOD_NOT_IMPLEMENTED

ERR_METHOD_NOT_IMPLEMENTED

Error message

The open() method is not implemented

What it means

When fs.createReadStream/fs.createWriteStream are built over an existing FileHandle (options.fd), the stream's internal fs-operation table is swapped for FileHandleOperations, whose open() entry always throws ERR_METHOD_NOT_IMPLEMENTED: the file is already open, so there is nothing to reopen. The normal stream lifecycle never calls it (stream.fd is already a number and _construct short-circuits), so this error means code explicitly drove the open path on a handle-based stream.

Source

Thrown at ext/node/polyfills/internal/fs/streams.mjs:112

        if (er) {
          callback(er);
        } else {
          stream.fd = fd;
          callback();
          stream.emit("open", stream.fd);
          stream.emit("ready");
        }
      },
    );
  }
}
/**
 * @param {import("node:fs/promises").FileHandle} handle
 */
const FileHandleOperations = (handle) => {
  return {
    open: (_path, _flags, _mode, _cb) => {
      throw new ERR_METHOD_NOT_IMPLEMENTED("open()");
    },
    close: (_fd, cb) => {
      handle[kUnref]();
      PromisePrototypeThen(handle.close(), () => cb(), cb);
    },
    fsync: (_fd, cb) => {
      PromisePrototypeThen(handle.sync(), () => cb(), cb);
    },
    read: (_fd, buf, offset, length, pos, cb) => {
      PromisePrototypeThen(
        handle.read(buf, offset, length, pos),
        // deno-lint-ignore deno-internal/prefer-primordials
        (r) => cb(null, r.bytesRead, r.buffer),
        (err) => cb(err, 0, buf),
      );
    },
    write: (_fd, buf, offset, length, pos, cb) => {
      PromisePrototypeThen(

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Do not call open on fd-based streams; the handle is already open
  2. Pass a path instead of a handle if you need open semantics: fs.createReadStream(path, opts)
  3. In wrappers, skip open when the fd is already set: if (stream.fd == null) stream.open()
  4. Catch ERR_METHOD_NOT_IMPLEMENTED in generic drivers as the signal that a stream is handle-backed, and treat it as already-open

Example fix

// before
function ensureOpen(stream) {
  stream.open(); // throws for createReadStream(null, { fd: handle })
}

// after
function ensureOpen(stream) {
  if (stream.fd == null) stream.open(); // fd already set => handle-backed, skip
}
Defensive patterns

Strategy: validation

Validate before calling

function ensureOpen(stream) {
  // fd already assigned => stream was built on an fd/FileHandle; open() is intentionally unimplemented
  if (stream.fd == null && typeof stream.open === 'function') stream.open();
}

Type guard

const isHandleBacked = (stream) => Number.isInteger(stream.fd) && (stream.path === undefined || stream.path === null);

Try / catch

try { stream.open(); } catch (e) { if (e?.code === 'ERR_METHOD_NOT_IMPLEMENTED') return; // already open via FileHandle; nothing to do
 throw e; }

Prevention

When it happens

Trigger: Monkey-patching or calling stream.open on a stream created with { fd: fileHandle }; a generic stream wrapper that unconditionally invokes open on every stream; re-triggering construction/open after autoClose set stream.fd back to null; test harnesses that force-open all streams regardless of construction.

Common situations: Porting path-based stream code to fd-based without removing the manual open call; graceful-fs-style wrapper libraries that patch open across all streams; reopen-on-error retry logic that does not know the stream was handle-backed.

Related errors


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