denoland/deno · error · TypeError
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
The "fd" argument must be of type number or an instance of FileHandle. Received ${fd} What it means
respondWithFD() accepts an fd that is either a raw numeric file descriptor or a FileHandle (from fs/promises open). Anything else — most commonly a file path string — throws ERR_INVALID_ARG_TYPE listing the accepted types.
Source
Thrown at ext/node/polyfills/http2.ts:3312
}
if (
options.statCheck !== undefined &&
typeof options.statCheck !== "function"
) {
throw new ERR_INVALID_ARG_VALUE("options.statCheck", options.statCheck);
}
let streamOptions = 0;
if (options.waitForTrailers) {
streamOptions |= STREAM_OPTION_GET_TRAILERS;
this[kState].flags |= STREAM_FLAGS_HAS_TRAILERS;
}
if (ObjectPrototypeIsPrototypeOf(FsFileHandle.prototype, fd)) {
fd = fd.fd;
} else if (typeof fd !== "number") {
throw new ERR_INVALID_ARG_TYPE("fd", ["number", "FileHandle"], fd);
}
debugStreamObj(this, "initiating response from fd");
this[kUpdateTimer]();
this.ownsFd = false;
const {
headers,
statusCode,
} = prepareResponseHeadersObject(headersParam, options);
setOtelServerStatus(this, statusCode);
// Payload/DATA frames are not permitted in these cases
if (
statusCode === HTTP_STATUS_NO_CONTENT ||
statusCode === HTTP_STATUS_RESET_CONTENT ||
statusCode === HTTP_STATUS_NOT_MODIFIED ||View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use respondWithFile(path, ...) when you only have a path
- Open the file first: const handle = await fs.promises.open(path, 'r'); then pass handle or handle.fd
- Validate before the call: typeof fd === 'number' || (fd && typeof fd.fd === 'number')
- Close the handle yourself afterwards — respondWithFD sets ownsFd = false and will not close it
Example fix
// before
stream.respondWithFD("/srv/big.bin", headers); // path string, not fd
// after
const handle = await fs.promises.open("/srv/big.bin", "r");
stream.respondWithFD(handle, headers);
stream.on("close", () => handle.close()); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof fd !== "number" && !(fd && typeof fd.fd === "number")) {
// you probably have a path: use respondWithFile instead
stream.respondWithFile(path, headers);
return;
} Type guard
function isFdLike(fd) {
return typeof fd === "number" || (typeof fd === "object" && fd !== null && typeof fd.fd === "number");
} Try / catch
try {
stream.respondWithFD(fd, headers);
} catch (err) {
if (err.code === "ERR_INVALID_ARG_TYPE") { /* fall back to respondWithFile(path) */ }
throw err;
} Prevention
- Have only a path? Use respondWithFile(path, ...). Have an open handle? Use respondWithFD(handle, ...)
- Remember respondWithFD does not close your FileHandle — close it on stream close
When it happens
Trigger: Passing a path string instead of an opened descriptor (confusing respondWithFD with respondWithFile); passing a closed or fake object without an fd property; passing a Deno FsFile where FileHandle.prototype check fails.
Common situations: Migrating code between respondWithFile and respondWithFD; using callback-style fs.open and passing the path 'by habit'; holding a FileHandle from a different fs surface whose prototype does not match.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- ERR_HTTP2_PAYLOAD_FORBIDDEN
- ERR_HTTP2_INVALID_INFO_STATUS
- ERR_MISSING_ARGS
- No callback function supplied
- ERR_INVALID_ARG_TYPE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/080bd0b9f951e6d1.
Report an issue: GitHub.