vitest-dev/vitest · error · Error

Expected "vitest" as the first argument, received

Error message

Expected "vitest" as the first argument, received "${arrayArgs[0]}"

What it means

`parseCLI` expects the argv array (or space-split argv string) to begin with the literal token `vitest`, because Vitest's internal `cac` parser is shaped around a `vitest` invocation. If the first element is anything else, it refuses to parse rather than producing a confusing downstream options object.

Solutions

  1. Prepend `vitest` to the argv: `parseCLI('vitest run --reporter=dot')`.
  2. When passing an array use `['vitest', ...rest]`.
  3. If you only have post-bin argv, prefix it: `parseCLI(['vitest', ...process.argv.slice(2)])`.

Example fix

// before
import { parseCLI } from 'vitest/node'
parseCLI('run --reporter=dot')

// after
parseCLI('vitest run --reporter=dot')
// or
parseCLI(['vitest', 'run', '--reporter=dot'])
Defensive patterns

Strategy: validation

Validate before calling

function toVitestArgv(argv: string | string[]): string[] {
  const arr = typeof argv === 'string' ? argv.split(' ') : argv
  return arr[0] === 'vitest' ? arr : ['vitest', ...arr]
}

const { filter, options } = parseCLI(toVitestArgv(userArgv))

Prevention

When it happens

Trigger: Calling `parseCLI('run --reporter=dot')` (missing `vitest` prefix), `parseCLI(['node', 'vitest', 'run'])`, or programmatically splitting an argv that does not start with the runner name. Also triggered by tests or tooling that build argv from `process.argv.slice(2)` and forget to prepend the binary name.

Common situations: Programmatic consumers of `parseCLI`; a wrapper script that strips `node`/binary from argv; an IDE integration that constructs argv from selected file paths only.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/node/cli/cac.ts:239

  return str
}

function splitArgv(argv: string): string[] {
  const reg = /(['"])(?:(?!\1).)+\1/g
  argv = argv.replace(reg, match => match.replace(/\s/g, '\x00'))
  return argv.split(' ').map((arg: string) => {
    arg = arg.replace(/\0/g, ' ')
    return removeQuotes(arg)
  })
}

export function parseCLI(argv: string | string[], config: CliParseOptions = {}): {
  filter: string[]
  options: CliOptions
} {
  const arrayArgs = typeof argv === 'string' ? splitArgv(argv) : argv
  if (arrayArgs[0] !== 'vitest') {
    throw new Error(`Expected "vitest" as the first argument, received "${arrayArgs[0]}"`)
  }
  arrayArgs[0] = '/index.js'
  arrayArgs.unshift('node')
  let { args, options } = createCLI(config).parse(arrayArgs, {
    run: false,
  })
  if (arrayArgs[2] === 'watch' || arrayArgs[2] === 'dev') {
    options.watch = true
  }
  if (arrayArgs[2] === 'run' && !options.watch) {
    options.run = true
  }
  if (arrayArgs[2] === 'related') {
    options.related = args
    options.passWithNoTests ??= true
    args = []
  }
  return {

View on GitHub (pinned to 1fa9837ec2)