denoland/deno · error · TypeError
ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
Error message
The property 'options.objectMode' is not supported. Received ${inspected} What it means
Deno's node:net polyfill rejects the `objectMode` option in the `net.Socket` constructor. A socket is a byte stream and only moves Buffer and string chunks, so object mode has no meaning on it. The polyfill throws ERR_INVALID_ARG_VALUE at construction time instead of silently ignoring the option.
Source
Thrown at ext/node/polyfills/net.ts:1479
*
* It can also be created by Node.js and passed to the user when a connection
* is received. For example, it is passed to the listeners of a `"connection"` event emitted on a `Server`, so the user can use
* it to interact with the client.
*/
function Socket(options) {
if (!ObjectPrototypeIsPrototypeOf(Socket.prototype, this)) {
return new Socket(options);
}
if (typeof options === "number") {
// Legacy interface.
options = { fd: options };
} else {
options = { ...options };
}
if (options.objectMode) {
throw new ERR_INVALID_ARG_VALUE(
"options.objectMode",
options.objectMode,
"is not supported",
);
}
if (options.readableObjectMode) {
throw new ERR_INVALID_ARG_VALUE(
"options.readableObjectMode",
options.readableObjectMode,
"is not supported",
);
}
if (options.writableObjectMode) {
throw new ERR_INVALID_ARG_VALUE(
"options.writableObjectMode",
options.writableObjectMode,
"is not supported",
);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Remove `objectMode` from the object passed to `new net.Socket(...)`.
- If you need objects over the wire, keep the socket in binary mode and serialize with JSON.stringify on write and JSON.parse on 'data'.
- Move object mode into a wrapping `stream.Duplex({ objectMode: true })` and connect it to the socket with pipe().
- Filter known-unsupported keys (`objectMode`, `readableObjectMode`, `writableObjectMode`) out of shared options before constructing the socket.
Example fix
// before
new net.Socket({ objectMode: true, port: 5432 });
// after — keep the socket in binary mode and serialize objects yourself
const socket = new net.Socket({ port: 5432 });
socket.write(JSON.stringify({ id: 1 }));
socket.on('data', (chunk) => handle(JSON.parse(chunk.toString()))); Defensive patterns
Strategy: validation
Validate before calling
const OBJECT_MODE_KEYS = ['objectMode', 'readableObjectMode', 'writableObjectMode'];
function assertNoObjectMode(opts) {
for (const key of OBJECT_MODE_KEYS) {
if (opts?.[key]) throw new Error(`net.Socket does not support ${key}`);
}
}
// before constructing:
assertNoObjectMode(socketOpts);
const socket = new net.Socket(socketOpts); Type guard
type ByteSocketOptions = Omit<net.SocketConstructorOpts, 'objectMode' | 'readableObjectMode' | 'writableObjectMode'>;
function isByteSocketOptions(v: unknown): v is ByteSocketOptions {
if (typeof v !== 'object' || v === null) return false;
const o = v as Record<string, unknown>;
return !o.objectMode && !o.readableObjectMode && !o.writableObjectMode;
} Try / catch
try {
socket = new net.Socket(opts);
} catch (err) {
if (err?.code === 'ERR_INVALID_ARG_VALUE' && /objectMode/.test(err.message)) {
const { objectMode, readableObjectMode, writableObjectMode, ...rest } = opts;
socket = new net.Socket(rest);
} else throw err;
} Prevention
- Never spread a shared stream-options object into net.Socket; pass an explicit minimal object.
- Keep serialization (JSON lines, msgpack) at the edges of the socket, not object mode on the socket.
- In cross-runtime libraries, unit-test socket construction with the library's real options object under Deno.
When it happens
Trigger: Constructing `new net.Socket({ objectMode: true })`, or `new net.Socket({ objectMode: true, fd: 3 })`. Also any factory that forwards a shared stream-options object into the Socket constructor, because the check runs before anything else in the constructor.
Common situations: Porting a library that switches a pipeline into object mode and reuses the same options object for sockets. Generic createStream(options) helpers that spread every stream option into every stream constructor. Code that runs unchanged on Node (which accepts the option) and then fails under Deno.
Related errors
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/59e615b357fb15d5.
Report an issue: GitHub.