denoland/deno · error · ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
The "ext" argument must be of type string. Received ${received} What it means
`path.win32.basename(path, ext)` requires the second argument to be a string or undefined, and throws ERR_INVALID_ARG_TYPE otherwise. `null` throws because the default parameter only covers undefined. This mirrors the posix basename check.
Source
Thrown at ext/node/polyfills/path/_win32.ts:874
matchedSlash = false;
}
}
if (end === -1) {
if (rootEnd === -1) return ".";
else end = rootEnd;
}
return StringPrototypeSlice(path, 0, end);
}
/**
* Return the last portion of a `path`. Trailing directory separators are ignored.
* @param path to process
* @param ext of path directory
*/
function basename(path: string, ext = ""): string {
if (ext !== undefined && typeof ext !== "string") {
throw new ERR_INVALID_ARG_TYPE("ext", ["string"], ext);
}
assertPath(path);
let start = 0;
let end = -1;
let matchedSlash = true;
let i: number;
// Check for a drive letter prefix so as not to mistake the following
// path separator as an extra separator at the end of the path that can be
// disregarded
if (path.length >= 2) {
const drive = StringPrototypeCharCodeAt(path, 0);
if (isWindowsDeviceRoot(drive)) {
if (StringPrototypeCharCodeAt(path, 1) === CHAR_COLON) start = 2;
}
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Omit the ext argument when you do not need it.
- Null-safe the lookup: `file.match(/\.[^.]+$/)?.[0] ?? ''`.
- Coerce explicitly with `String(ext)` when coercion is intended.
- Default the parameter at your own wrapper: `basename(p, ext = '')`.
Example fix
// before const ext = file.match(/\.[^.]+$/); // null when no match path.win32.basename(file, ext); // after const ext = file.match(/\.[^.]+$/)?.[0] ?? ''; path.win32.basename(file, ext);
Defensive patterns
Strategy: type-guard
Validate before calling
const safeExt = (ext) => (ext == null ? '' : String(ext)); path.win32.basename(file, safeExt(ext));
Type guard
function isOptionalString(v: unknown): v is string | undefined {
return v === undefined || typeof v === 'string';
} Prevention
- Use null-safe extraction for computed extensions: match(...)?.[0] ?? ''.
- Default the ext parameter in wrappers around basename.
- Remember null throws while undefined does not — normalize before the call.
When it happens
Trigger: `path.win32.basename(file, null)` from a match/lookup that returned null; `path.win32.basename(p, 5)`; passing an object in place of ext. Note `path.basename` on Windows uses this win32 implementation.
Common situations: Extension computed with `String.prototype.match()` returning null. Optional ext parameters with no default. Cross-platform filename handling shared between posix and win32 call sites.
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_INVALID_ARG_TYPE
- ERR_INVALID_ARG_TYPE
- Resolved a drive-letter-less path without a CWD.
- Resolved a relative path without a CWD.
- ERR_INVALID_ARG_TYPE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/8dea96adbe261e08.
Report an issue: GitHub.