vitest-dev/vitest · error · Error

Expected "vitest" as the first argument, received "${arrayAr

Error message

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

What it means

Thrown by parseCLI() when the first element of the argv array is not the literal string "vitest". parseCLI is the internal entry that expects exactly the Vitest subcommand vector (starting with the program name "vitest"); it then rewrites argv[0] and prepends "node" for the cac parser. Any other first token means the caller passed the wrong argv shape.

Source

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

  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 d568f8ce37)

Solutions

  1. If using Vitest programmatically, prefer the `startVitest`/`Vitest` API or the `vitest node` entry instead of parseCLI.
  2. If you must call parseCLI, ensure argv[0] === 'vitest' (e.g. parseCLI('vitest run')).
  3. Do not pass raw process.argv; strip the node binary and script, then prepend 'vitest'.

Example fix

// before
parseCLI(process.argv)
// after
parseCLI(['vitest', 'run', 'src'])
Defensive patterns

Strategy: validation

Validate before calling

const argv = typeof input === 'string' ? input : input
const arr = typeof argv === 'string' ? argv.split(' ') : argv
if (arr[0] !== 'vitest') arr.unshift('vitest')
parseCLI(arr)

Prevention

When it happens

Trigger: Calling parseCLI with the full `process.argv` (which starts with the node binary path), passing argv without the leading "vitest" token, or calling it from a wrapper that strips the program name. parseCLI is meant for the `vitest` CLI front-end only.

Common situations: Writing a custom CLI wrapper around Vitest and forwarding process.argv directly; integrating Vitest programmatically and mistakenly routing through parseCLI instead of the Vitest/Mocha API; a shell alias that invokes node with the script path.


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/3beba4d38f81f237.json. Report an issue: GitHub.