koala73/worldmonitor · error · Error
No test files match ${pattern}
Error message
No test files match ${pattern} What it means
For each positional argument, run-data-tests.mjs first checks if the pattern is an existing file, otherwise expands it with globSync. If a pattern expands to zero matches it throws `No test files match ${pattern}` so typos or wrong paths fail fast instead of silently running zero tests.
Solutions
- Verify the glob from the same working directory: `ls tests/data/*.test.mjs` — fix typos or path prefixes
- Check that the command runs from the repository root (globs are relative to cwd)
- If a file was intentionally passed, confirm it exists (`test -f <path>`); if a glob is correct, confirm the test files actually exist in the checkout
Example fix
// before node scripts/run-data-tests.mjs 'tests/unit/**/*.test.js' // after (match the actual layout) node scripts/run-data-tests.mjs 'tests/unit/**/*.test.mjs'
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, statSync, globSync } from 'node:fs';
for (const pattern of patterns) {
const ok = (existsSync(pattern) && statSync(pattern).isFile()) || globSync(pattern).length > 0;
if (!ok) throw new Error(`No test files match ${pattern} (cwd=${process.cwd()})`);
} Type guard
const patternMatchesFiles = (pattern) => (existsSync(pattern) && statSync(pattern).isFile()) || globSync(pattern).length > 0;
Try / catch
try {
await run();
} catch (err) {
const m = err.message.match(/^No test files match (.+)$/);
if (m) {
console.error(`Glob ${m[1]} matched nothing. cwd=${process.cwd()}. Check the path and that test files exist.`);
process.exit(2);
}
throw err;
} Prevention
- Run globs from the repository root; print cwd when debugging
- Keep glob patterns in a single config/variable and verify them with `ls` or globSync in a dry run
- When renaming/moving test files, grep CI configs and scripts for the old paths
- Quote globs on the command line so the shell does not pre-expand them inconsistently
When it happens
Trigger: Calling the runner with a positional that is neither an existing file nor a matching glob, e.g. `node scripts/run-data-tests.mjs 'tests/data/*.spec.mjs'` when no .spec.mjs files exist, or a typo like 'tests/data/**/*test.mjs'.
Common situations: Working from the wrong working directory so relative globs match nothing; renaming/moving test directories so stale globs in CI configs break; quoting issues where the shell already expanded (or failed to expand) the glob; case-sensitive filesystem mismatches.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Supply test files or globs
- Shard count exceeds the test file count
- The selected shard contains no test files
- global fetch is unavailable — Node 18+ is required
- --args must be valid JSON: ${err.message}
AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15).
Data as JSON: /api/errors/5af73e866b21bb70.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/run-data-tests.mjs:57
});
if (!/^[1-9]\d*$/.test(values.concurrency) || !Number.isSafeInteger(Number(values.concurrency))) {
throw new Error('Concurrency must be a positive integer');
}
let index = 1;
let total = 1;
if (values.shard) {
const match = /^([1-9]\d*)\/([1-9]\d*)$/.exec(values.shard);
if (!match) throw new Error('Shard must be INDEX/TOTAL (for example 1/2)');
[index, total] = match.slice(1).map(Number);
if (!Number.isSafeInteger(index) || !Number.isSafeInteger(total) || index > total) {
throw new Error('Shard index must be between 1 and TOTAL');
}
}
if (!positionals.length) throw new Error('Supply test files or globs');
const files = [...new Set(positionals.flatMap((pattern) => {
const matches = (existsSync(pattern) && statSync(pattern).isFile() ? [pattern] : globSync(pattern))
.map((file) => file.split(sep).join('/'));
if (!matches.length) throw new Error(`No test files match ${pattern}`);
return matches;
}))];
const durations = JSON.parse(readFileSync(timingPath, 'utf8'));
if (total > files.length) throw new Error('Shard count exceeds the test file count');
const selected = partitionTests(files, durations, total)[index - 1];
if (!selected.length) throw new Error('The selected shard contains no test files');
if (values.list) {
console.log(JSON.stringify(selected));
return 0;
}
console.log(`Data tests: ${selected.length}/${files.length} files, shard ${index}/${total}, concurrency ${values.concurrency}`);
const env = { ...process.env };
// This is a new test run, even when a contract test invokes the CLI.
delete env.NODE_TEST_CONTEXT;
const timingFd = values.timings ? openSync(values.timings, 'w') : undefined;
let success = false;
try {
const events = run({View on GitHub (pinned to 7d06c8633d)