denoland/deno · error · NodeTypeError
ERR_MISSING_ARGS
ERR_MISSING_ARGS
Error message
The "path" argument must be specified
What it means
The internal Dir class behind fs.opendir()/fs.opendirSync() throws ERR_MISSING_ARGS when constructed with a falsy path. The public fs.opendir entry points validate the path themselves, so reaching this usually means an empty string or undefined slipped past upstream validation, or the internal class was used directly.
Source
Thrown at ext/node/polyfills/_fs/_fs_dir.ts:38
SymbolAsyncIterator,
SymbolAsyncDispose,
SymbolDispose,
ArrayIteratorPrototypeNext,
SymbolIterator,
} = primordials;
// Note: unlike `fs.readdir`, `fs.opendir`/`Dir` streams entries in filesystem
// order and does NOT sort them, matching Node.js (libuv's `uv_fs_readdir`, as
// opposed to `uv_fs_scandir` which backs `readdir`). Do not add sorting here.
export default class Dir {
#dirPath: string | Uint8Array;
#syncIterator!: Iterator<Deno.DirEntry, undefined> | null;
#asyncIterator!: AsyncIterator<Deno.DirEntry, undefined> | null;
#closed = false;
constructor(path: string | Uint8Array) {
if (!path) {
throw new ERR_MISSING_ARGS("path");
}
this.#dirPath = path;
}
get path(): string {
if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, this.#dirPath)) {
return new TextDecoder().decode(this.#dirPath);
}
return this.#dirPath;
}
// deno-lint-ignore no-explicit-any
read(callback?: (...args: any[]) => void): Promise<Dirent | null> {
return new Promise((resolve, reject) => {
if (this.#closed) {
const err = new ERR_DIR_CLOSED();
if (callback) {
callback(err);View on GitHub (pinned to 89f33cbef2)
Solutions
- Pass a concrete non-empty path (string, Buffer, or URL)
- Validate before the call: if (!path) throw new Error('path required')
- Log the offending value at the call site to find which stage of your pipeline lost it
Example fix
// before
fs.opendir(dirName, (err, d) => { ... }); // dirName is undefined/''
// after
if (typeof dirName !== "string" || dirName === "") {
throw new Error("opendir requires a non-empty path");
}
fs.opendir(dirName, (err, d) => { ... }); Defensive patterns
Strategy: validation
Validate before calling
function toNonEmptyPath(p: string | Buffer | URL | undefined): string | Buffer | URL {
if (p === undefined || p === null || p === "") {
throw new Error("A non-empty path is required for directory operations");
}
return p;
}
const dir = fs.opendirSync(toNonEmptyPath(config.dir)); Type guard
function isValidDirPath(p: unknown): p is string | Buffer | URL {
if (typeof p === "string") return p.length > 0;
return p instanceof Buffer || p instanceof URL;
} Prevention
- Default optional config paths at load time instead of letting undefined flow into fs calls
- Validate user-supplied paths at the API boundary with one shared helper
- Log the raw value when path validation fails to locate the pipeline stage that lost it
When it happens
Trigger: fs.opendir(undefined) or fs.opendir('') on a code path where earlier validation is bypassed; constructing the internal Dir class directly from polyfill internals.
Common situations: Path assembled from optional config that is undefined when unset; destructuring that misses/renames the path variable; empty string left after trimming user input.
Related errors
- A file exists at the destination: ${destStr}
- ERR_DIR_CLOSED
- No callback function supplied
- ERR_INVALID_ARG_TYPE
- invalid ${name}, must not be infinity or NaN
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/bd75b0abfe43dea1.
Report an issue: GitHub.