{"id":"d0eef8c3088e5748","repo":"vitest-dev/vitest","slug":"shard-count-must-be-a-smaller-than-count-of-te","errorCode":null,"errorMessage":"--shard <count> must be a smaller than count of test files. Resolved ${specs.length} test files for --shard=${ctx.config.shard.index}/${ctx.config.shard.count}.","messagePattern":"--shard <count> must be a smaller than count of test files\\. Resolved (.+?) test files for --shard=(.+?)/(.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/pool.ts","lineNumber":74,"sourceCode":"  const pool = new Pool({\n    distPath: ctx.distPath,\n    teardownTimeout: ctx.config.teardownTimeout,\n    state: ctx.state,\n  }, ctx.logger)\n\n  const options = resolveOptions(ctx)\n\n  const Sequencer = ctx.config.sequence.sequencer\n  const sequencer = new Sequencer(ctx)\n\n  let browserPool: ProcessPool | undefined\n\n  async function executeTests(method: 'run' | 'collect', specs: TestSpecification[], invalidates?: string[]): Promise<void> {\n    ctx.onCancel(() => pool.cancel())\n\n    if (ctx.config.shard) {\n      if (!ctx.config.passWithNoTests && ctx.config.shard.count > specs.length) {\n        throw new Error(\n          '--shard <count> must be a smaller than count of test files. '\n          + `Resolved ${specs.length} test files for --shard=${ctx.config.shard.index}/${ctx.config.shard.count}.`,\n        )\n      }\n      specs = await sequencer.shard(Array.from(specs))\n    }\n\n    const taskGroups: {\n      tasks: PoolTask[]\n      maxWorkers: number\n      // browser pool has a more complex logic, so we keep it separately for now\n      browserSpecs: TestSpecification[]\n    }[] = []\n    let workerId = 1\n\n    const sorted = await sequencer.sort(specs)\n    const { environments, tags } = await getSpecificationsOptions(specs)\n    const groups = groupSpecs(sorted, environments)","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/pool.ts#L56-L92","documentation":"Thrown when the configured shard count exceeds the number of resolved test files. Vitest shards tests by splitting the file list across shard indices, so each shard must map to at least one file; if you ask for more shards than files, some shards would receive nothing and the run is considered misconfigured. This is a hard failure unless passWithNoTests is enabled (in which case empty shards are allowed).","triggerScenarios":"Configuring config.shard with { index, count } where count > number of collected test files, OR passing --shard=N/M on the CLI with M greater than the resolved spec count, AND config.passWithNoTests is false (the default). The check is at packages/vitest/src/node/pool.ts:73 against specs.length after collecting TestSpecifications.","commonSituations":"Running --shard=2/4 in a CI matrix where a previous filter/changed-files flag left fewer than 4 test files; using sharding in a small project with only 1-2 test files; sharding a workspace where only one project matched the file glob this run.","solutions":["Reduce the shard count (--shard=N/M, lower M) to be <= the number of test files in this run.","Remove the --shard flag if you do not actually need parallel CI sharding for this small suite.","If empty shards are acceptable for your CI setup, set passWithNoTests: true in the vitest config so the guard is skipped.","Ensure your include globs and changed-files/dependency filters actually resolve the files you expect before sharding."],"exampleFix":"// before (CI matrix of 4, but only 2 files match)\nvitest run --shard=1/4\n\n// after\nvitest run --shard=1/2\n// or allow empty shards in config:\nexport default defineConfig({\n  test: { passWithNoTests: true },\n})","handlingStrategy":"validation","validationCode":"// Before running, confirm the shard fits the resolved spec count\nimport { glob } from 'tinyglobby'\n\nasync function canShard(includeGlobs, shard) {\n  const files = await glob(includeGlobs, { absolute: true })\n  return shard.count <= files.length\n}\n\nif (config.shard && !config.passWithNoTests) {\n  const ok = await canShard(config.include, config.shard)\n  if (!ok) throw new Error(`Cannot shard ${resolved} files into ${config.shard.count}`)\n}","typeGuard":"// Validate the shard config shape and feasibility against a known file count\nfunction isValidShard(shard, fileCount) {\n  return (\n    shard == null\n    || (typeof shard.index === 'number'\n      && typeof shard.count === 'number'\n      && shard.index >= 1\n      && shard.index <= shard.count\n      && (shard.count <= fileCount))\n  )\n}","tryCatchPattern":"// Catch at the run boundary and report a friendlier message\ntry {\n  await vitest.start()\n} catch (e) {\n  if (e.message.startsWith('--shard')) {\n    console.error('Sharding misconfigured:', e.message)\n    process.exit(1)\n  }\n  throw e\n}","preventionTips":["Size CI shard matrices to the minimum expected file count across all branches/filters.","Set passWithNoTests: true in CI if shards may legitimately be empty.","Log the resolved spec count before sharding when debugging CI matrices."],"tags":["sharding","config","cli"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}