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
- Do not call open on fd-based streams; the handle is already open
- Pass a path instead of a handle if you need open semantics: fs.createReadStream(path, opts)
- In wrappers, skip open when the fd is already set: if (stream.fd == null) stream.open()
- 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
- Treat fd-based streams as pre-opened: check stream.fd before any open call
- Choose path-based createReadStream when your wrapper needs open semantics
- Do not monkey-patch open() on handle-backed streams
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
- EBADF
- A file exists at the destination: ${destStr}
- ERR_MISSING_ARGS
- ERR_DIR_CLOSED
- No callback function supplied
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/df52d4c5a6daaae3.
Report an issue: GitHub.