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.posix.basename(path, ext)` requires the second argument to be a string or undefined. The polyfill throws ERR_INVALID_ARG_TYPE for any other type. `null` throws too, because the default parameter only replaces undefined.
Source
Thrown at ext/node/polyfills/path/_posix.ts:283
} else {
// We saw the first non-path separator
matchedSlash = false;
}
}
if (end === -1) return hasRoot ? "/" : ".";
if (hasRoot && end === 1) return "//";
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;
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
if (ext.length === path.length && ext === path) return "";
let extIdx = ext.length - 1;
let firstNonSlashEnd = -1;
for (i = path.length - 1; i >= 0; --i) {
const code = StringPrototypeCharCodeAt(path, i);
if (code === CHAR_FORWARD_SLASH) {
// If we reached a path separator that was not part of a set of path
// separators at the end of the string, stop now
if (!matchedSlash) {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 when coercion is intended: `String(ext)`.
- Default destructure the parameter: `function base(p, ext = '')`.
Example fix
// before const ext = file.match(/\.[^.]+$/); // null when no extension path.basename(file, ext); // after const ext = file.match(/\.[^.]+$/)?.[0] ?? ''; path.basename(file, ext);
Defensive patterns
Strategy: type-guard
Validate before calling
const safeExt = (ext) => (ext == null ? '' : String(ext)); path.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 your own wrappers: basename(p, ext = '').
- Remember null throws while undefined does not — normalize null to undefined or ''.
When it happens
Trigger: `path.basename(file, null)` from a regex match or indexOf-style lookup that returned null; `path.basename(p, 5)`; passing an options object in place of ext; `path.basename(p, ext)` where ext came from destructured config.
Common situations: Extension computed with `String.prototype.match()` that returns null when there is no match. Optional config fields with no default. Porting shell habits where the extension filter is a separate flag.
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
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_FILE_URL_HOST
- Host must be empty
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/d2829f6b83765f9f.
Report an issue: GitHub.