denoland/deno · error · ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

ERR_INVALID_ARG_TYPE

Error message

The "path" argument must be of type string. Received ${received}

What it means

`assertPath` runs at the top of nearly every path function (join, resolve, basename, extname, relative, parse, and more) in both the posix and win32 implementations. It throws ERR_INVALID_ARG_TYPE when a processed path value is not a string. A single undefined segment inside `path.join` is enough.

Source

Thrown at ext/node/polyfills/path/_util.ts:26

  CHAR_DOT,
  CHAR_FORWARD_SLASH,
  CHAR_LOWERCASE_A,
  CHAR_LOWERCASE_Z,
  CHAR_UPPERCASE_A,
  CHAR_UPPERCASE_Z,
} = core.loadExtScript("ext:deno_node/path/_constants.ts");
const { ERR_INVALID_ARG_TYPE } = core.loadExtScript(
  "ext:deno_node/internal/errors.ts",
);
const {
  StringPrototypeCharCodeAt,
  StringPrototypeLastIndexOf,
  StringPrototypeSlice,
} = primordials;

function assertPath(path: string) {
  if (typeof path !== "string") {
    throw new ERR_INVALID_ARG_TYPE("path", ["string"], path);
  }
}

function isPosixPathSeparator(code: number): boolean {
  return code === CHAR_FORWARD_SLASH;
}

function isPathSeparator(code: number): boolean {
  return isPosixPathSeparator(code) || code === CHAR_BACKWARD_SLASH;
}

function isWindowsDeviceRoot(code: number): boolean {
  return (
    (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z) ||
    (code >= CHAR_UPPERCASE_A && code <= CHAR_UPPERCASE_Z)
  );
}

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Default optional inputs before use: `process.env.HOME ?? '.'`.
  2. Convert URL objects with `url.fileURLToPath(url)` before passing to path functions.
  3. Convert numbers with `String(n)` when the number is a path by contract.
  4. Fail fast with a clear message when a required path segment is missing, instead of letting it flow into path.join.

Example fix

// before
path.join(projectRoot, process.env.REL_PATH); // undefined when unset

// after
path.join(projectRoot, process.env.REL_PATH ?? '.');
Defensive patterns

Strategy: type-guard

Validate before calling

const segments = [dir, name, suffix].filter((s) => typeof s === 'string');
const full = path.join(...segments); // skip missing parts instead of passing undefined

Type guard

function isPathSegment(v: unknown): v is string {
  return typeof v === 'string';
}

Prevention

When it happens

Trigger: `path.join(dir, filename)` where filename is undefined; `path.resolve(process.env.HOME)` with HOME unset; passing a `URL` object (path functions take strings, not URLs); numbers from config; `path.extname(someNumber)`.

Common situations: Missing environment variables. Optional object fields that were never set. Passing `import.meta.url` or `new URL(...)` directly instead of `url.fileURLToPath`. Numbers from CLI flags.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/116528cbf18d35a4. Report an issue: GitHub.