koala73/worldmonitor · error · Error

Shard count exceeds the test file count

Error message

Shard count exceeds the test file count

What it means

When --shard N/T is given, the runner partitions the resolved test files into t shards. If the requested total shard count t exceeds the number of resolved test files, some shards would be empty by construction, so it throws 'Shard count exceeds the test file count' to abort the run.

Solutions

  1. Lower the TOTAL in --shard to at most the number of matched files, e.g. --shard 1/5 for 5 files
  2. Add more files/globs so the count meets or exceeds the shard total
  3. Check which files the current globs resolve to and reconcile with the CI matrix shard count

Example fix

// before (3 files resolved)
node scripts/run-data-tests.mjs --shard 2/8 'tests/data/**/*.test.mjs'
// after
node scripts/run-data-tests.mjs --shard 2/3 'tests/data/**/*.test.mjs'
Defensive patterns

Strategy: validation

Validate before calling

import { globSync } from 'node:fs';
const fileCount = new Set(globs.flatMap(g => globSync(g))).size;
if (shardTotal > fileCount) {
  throw new Error(`--shard TOTAL (${shardTotal}) exceeds ${fileCount} resolved test files`);
}

Type guard

const shardCountIsValid = (total, files) => Number.isSafeInteger(total) && total >= 1 && total <= files.length;

Try / catch

try {
  await run();
} catch (err) {
  if (err.message === 'Shard count exceeds the test file count') {
    console.error(`Reduce --shard TOTAL to <= number of matched files (matched: ${files.length}).`);
    process.exit(2);
  }
  throw err;
}

Prevention

When it happens

Trigger: Running `node scripts/run-data-tests.mjs --shard 4/8 <globs>` where the globs resolve to fewer than 8 files, e.g. passing 5 files with `--shard 1/8`.

Common situations: Bumping CI matrix parallelism without shrinking the file list; narrowing the test globs (fewer files) while the CI matrix still requests more shards; a --shard TOTAL left at an old larger value after test files were removed.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@7d06c8633d (2026-09-15). Data as JSON: /api/errors/f08cd8585b671ea7. Report an issue: GitHub.

Appendix: source

Thrown at scripts/run-data-tests.mjs:61

  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({
      files: selected.map((file) => resolve(file)),
      concurrency: Number(values.concurrency),
      timeout: 120000,
      execArgv: ['--import', 'tsx'],

View on GitHub (pinned to 7d06c8633d)