vitest-dev/vitest · error · Error

--shard must be a positive number

Error message

--shard <count> must be a positive number

What it means

Vitest parses the `--shard <index>/<count>` string by splitting on `/` and integer-parsing both halves. The count (the denominator) must be a positive integer; this fires when it is missing, NaN, zero, or negative (the code applies `Math.abs`, so negative still resolves to its magnitude — NaN or 0 is the real trigger).

Solutions

  1. Format the shard as `<index>/<count>` with a positive integer count, e.g. `1/4`.
  2. Verify the env vars supplying the denominator are set and numeric.
  3. Echo the resolved shard string in your CI log before invoking vitest.

Example fix

# before
vitest --shard 2/
# after
vitest --shard 2/4
Defensive patterns

Strategy: validation

Validate before calling

function parseShard(raw: string): { index: number, count: number } {
  const [i, c] = raw.split('/')
  const index = Number.parseInt(i ?? '', 10)
  const count = Number.parseInt(c ?? '', 10)
  if (!Number.isInteger(count) || count <= 0) {
    throw new Error(`Invalid shard count in "${raw}"; expected <index>/<positive count>`)
  }
  if (!Number.isInteger(index) || index <= 0 || index > count) {
    throw new Error(`Invalid shard index in "${raw}"`)
  }
  return { index, count }
}

Type guard

function isValidShardString(raw: string): boolean {
  const m = /^(\d+)\/(\d+)$/.exec(raw)
  if (!m) return false
  const [, i, c] = m
  return Number(i) > 0 && Number(c) > 0 && Number(i) <= Number(c)
}

Prevention

When it happens

Trigger: Passing `--shard 2/`, `--shard 2/0`, `--shard 2/abc`, or `--shard 2` (no slash). Also `--shard 2/-3` resolves to count 3, so this specific error is really about NaN/0.

Common situations: CI matrix that builds the shard string from `CI_NODE_INDEX/CODEBUILD_NUM_SHARDS` style vars where the count var is empty; a typo'd shard literal.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/64c2f3383b41ba14. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/node/config/resolveConfig.ts:360

  }

  if (viteConfig.base !== '/') {
    resolved.base = viteConfig.base
  }

  resolved.clearScreen = resolved.clearScreen ?? viteConfig.clearScreen ?? true

  if (options.shard) {
    if (resolved.watch) {
      throw new Error('You cannot use --shard option with enabled watch')
    }

    const [indexString, countString] = options.shard.split('/')
    const index = Math.abs(Number.parseInt(indexString, 10))
    const count = Math.abs(Number.parseInt(countString, 10))

    if (Number.isNaN(count) || count <= 0) {
      throw new Error('--shard <count> must be a positive number')
    }

    if (Number.isNaN(index) || index <= 0 || index > count) {
      throw new Error(
        '--shard <index> must be a positive number less then <count>',
      )
    }

    resolved.shard = { index, count }
  }

  if (resolved.standalone && !resolved.watch) {
    throw new Error(`Vitest standalone mode requires --watch`)
  }

  if (resolved.mergeReports && resolved.watch) {
    throw new Error(`Cannot merge reports with --watch enabled`)
  }

View on GitHub (pinned to 1fa9837ec2)