denoland/deno · error · NodeTypeError
ERR_INVALID_ARG_TYPE
ERR_INVALID_ARG_TYPE
Error message
The "${name}[${i}]" argument must be of type string What it means
In fs.glob (and fs.promises.glob), options.exclude may be either an array of glob-pattern strings or a predicate function. validateStringArrayOrFunction checks each array element; a non-string element (number, null, undefined, RegExp) throws ERR_INVALID_ARG_TYPE naming options.exclude[i].
Source
Thrown at ext/node/polyfills/_fs/_fs_glob.ts:204
function getRealpathStringSync(path) {
try {
return op_require_real_path(path);
} catch {
return null;
}
}
/**
* @callback validateStringArrayOrFunction
* @param {*} value
* @param {string} name
*/
const validateStringArrayOrFunction = hideStackFrames((value, name) => {
if (ArrayIsArray(value)) {
for (let i = 0; i < value.length; ++i) {
if (typeof value[i] !== "string") {
throw new ERR_INVALID_ARG_TYPE(`${name}[${i}]`, "string", value[i]);
}
}
return;
}
if (typeof value !== "function") {
throw new ERR_INVALID_ARG_TYPE(name, ["string[]", "function"], value);
}
});
/**
* @param {string} pattern
* @param {options} options
* @returns {Minimatch}
*/
function createMatcher(pattern, options = kEmptyObject) {
const opts = {
__proto__: null,
nocase: isWindows || isMacOS,View on GitHub (pinned to 89f33cbef2)
Solutions
- Keep every exclude entry a string glob: ['dist/**', 'coverage/**']
- Convert RegExp filters to globs, or use the function form: exclude: (p) => re.test(p)
- Sanitize before passing: exclude.filter((x) => typeof x === 'string')
Example fix
// before
fs.glob("**/*.ts", { exclude: ["node_modules", /vendor/] }, cb);
// after
fs.glob("**/*.ts", { exclude: ["node_modules", "vendor/**"] }, cb);
// or the predicate form:
fs.glob("**/*.ts", { exclude: (p) => /vendor/.test(p) }, cb); Defensive patterns
Strategy: type-guard
Validate before calling
function normalizeExclude(v: unknown): string[] | ((p: string) => boolean) {
if (typeof v === "function") return v;
if (Array.isArray(v)) {
const strs = v.filter((x): x is string => typeof x === "string");
if (strs.length !== v.length) {
throw new Error(
"fs.glob options.exclude must be an array of glob strings or a function; found non-string entries - convert RegExp filters to the function form",
);
}
return strs;
}
throw new Error("options.exclude must be string[] or function");
} Type guard
function isStringArrayOrFunction(v: unknown): v is string[] | ((p: string) => boolean) {
if (typeof v === "function") return true;
return Array.isArray(v) && v.every((x) => typeof x === "string");
} Prevention
- Express exclusion filters as glob strings, or as one predicate function for RegExp logic
- Type options.exclude as string[] in TypeScript so numbers/nulls are rejected at compile time
- Filter config-derived arrays to strings before passing them into fs.glob
When it happens
Trigger: fs.glob('**/*.ts', { exclude: ['node_modules', /build/] }); exclude: ['dist', 42]; arrays built from config where some entries are undefined.
Common situations: Mixing RegExp filters into exclude (it expects glob strings); assembling exclude lists from heterogeneous config; spreading optional arrays that contain holes or nulls.
Related errors
- A file exists at the destination: ${destStr}
- ERR_MISSING_ARGS
- No callback function supplied
- invalid ${name}, must not be infinity or NaN
- ERR_INVALID_ARG_VALUE
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/b015384c9cade04b.
Report an issue: GitHub.