{"record":{"id":"0e5e51e3513cfe27","repo":"denoland/deno","slug":"err-invalid-arg-type-0e5e51","errorCode":"ERR_INVALID_ARG_TYPE","errorMessage":"The \"fd\" argument must be of type number","messagePattern":"The \"fd\" argument must be of type number","errorType":"validation","errorClass":"NodeTypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/fs.ts","lineNumber":544,"sourceCode":"      );\n    }\n    offset += lengths[i];\n  }\n}\n\nfunction readv(\n  fd: number,\n  buffers: readonly ArrayBufferView[],\n  callback: ReadvCallback,\n): void;\nfunction readv(\n  fd: number,\n  buffers: readonly ArrayBufferView[],\n  position: number | ReadvCallback,\n  callback?: ReadvCallback,\n): void {\n  if (typeof fd !== \"number\") {\n    throw new ERR_INVALID_ARG_TYPE(\"fd\", \"number\", fd);\n  }\n  fd = getValidatedFd(fd);\n  validateBufferArray(buffers);\n  const cb = maybeCallback(callback || position) as ReadvCallback;\n  let pos: number | null = null;\n  if (typeof position === \"number\") {\n    validateInteger(position, \"position\", 0);\n    pos = position;\n  }\n\n  if (buffers.length === 0) {\n    lazyProcess().default.nextTick(cb, null, 0, buffers);\n    return;\n  }\n  const { buffer, lengths, views } = prepareReadvBuffers(buffers, false);\n\n  PromisePrototypeThen(\n    op_node_fs_read_deferred(fd, buffer, pos === null ? -1n : BigInt(pos)),","sourceCodeStart":526,"sourceCodeEnd":562,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/node/polyfills/fs.ts#L526-L562","documentation":"fs.readv(fd, buffers[, position], callback) requires fd to be a number (a raw file descriptor from fs.open/openSync). The polyfill checks typeof fd !== 'number' first and throws ERR_INVALID_ARG_TYPE — FileHandle objects, strings, and undefined all fail before getValidatedFd runs.","triggerScenarios":"const fh = await fsPromises.open(f); fs.readv(fh, buffers, cb) (FileHandle instead of fh.fd); fs.readv('3', bufs, cb) (string from CLI/config); forgetting the open() call and passing undefined.","commonSituations":"Mixing fsPromises (FileHandle) with callback-style fs APIs; fds arriving as strings from environment/IPC; refactors where openSync was replaced by fsPromises.open.","solutions":["Use the numeric descriptor: fs.readv(fh.fd, buffers, cb) or keep fs.openSync() results","Convert external fd values: const n = Number(fd); if (!Number.isInteger(n)) throw ...","Prefer fs.createReadStream / fh.read() when you already hold a FileHandle"],"exampleFix":"// before\nconst fh = await fsPromises.open('data.bin', 'r');\nfs.readv(fh, [buf1, buf2], cb); // FileHandle is not a number -> throws\n\n// after\nfs.readv(fh.fd, [buf1, buf2], cb);","handlingStrategy":"type-guard","validationCode":"const fdNum = typeof fd === 'object' && fd !== null && typeof fd.fd === 'number'\n  ? fd.fd\n  : fd;\nif (typeof fdNum !== 'number' || !Number.isInteger(fdNum)) {\n  throw new TypeError('readv requires a numeric fd (use fh.fd for FileHandle)');\n}\nfs.readv(fdNum, buffers, cb);","typeGuard":"const isNumericFd = (v) => typeof v === 'number' && Number.isInteger(v);","tryCatchPattern":null,"preventionTips":["Pass fh.fd when you opened with fsPromises.open","Keep one fs style per module — promise FileHandles or numeric fds, not both","Coerce fds arriving over IPC/JSON with Number() plus an integer check"],"tags":["node-compat","fs","validation","file-descriptor"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}