{"record":{"id":"3beba4d38f81f237","repo":"vitest-dev/vitest","slug":"expected-vitest-as-the-first-argument-received","errorCode":null,"errorMessage":"Expected \"vitest\" as the first argument, received \"${arrayArgs[0]}\"","messagePattern":"Expected \"vitest\" as the first argument, received \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/cli/cac.ts","lineNumber":239,"sourceCode":"  return str\n}\n\nfunction splitArgv(argv: string): string[] {\n  const reg = /(['\"])(?:(?!\\1).)+\\1/g\n  argv = argv.replace(reg, match => match.replace(/\\s/g, '\\x00'))\n  return argv.split(' ').map((arg: string) => {\n    arg = arg.replace(/\\0/g, ' ')\n    return removeQuotes(arg)\n  })\n}\n\nexport function parseCLI(argv: string | string[], config: CliParseOptions = {}): {\n  filter: string[]\n  options: CliOptions\n} {\n  const arrayArgs = typeof argv === 'string' ? splitArgv(argv) : argv\n  if (arrayArgs[0] !== 'vitest') {\n    throw new Error(`Expected \"vitest\" as the first argument, received \"${arrayArgs[0]}\"`)\n  }\n  arrayArgs[0] = '/index.js'\n  arrayArgs.unshift('node')\n  let { args, options } = createCLI(config).parse(arrayArgs, {\n    run: false,\n  })\n  if (arrayArgs[2] === 'watch' || arrayArgs[2] === 'dev') {\n    options.watch = true\n  }\n  if (arrayArgs[2] === 'run' && !options.watch) {\n    options.run = true\n  }\n  if (arrayArgs[2] === 'related') {\n    options.related = args\n    options.passWithNoTests ??= true\n    args = []\n  }\n  return {","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/node/cli/cac.ts#L221-L257","documentation":"`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.","triggerScenarios":"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.","commonSituations":"Programmatic consumers of `parseCLI`; a wrapper script that strips `node`/binary from argv; an IDE integration that constructs argv from selected file paths only.","solutions":["Prepend `vitest` to the argv: `parseCLI('vitest run --reporter=dot')`.","When passing an array use `['vitest', ...rest]`.","If you only have post-bin argv, prefix it: `parseCLI(['vitest', ...process.argv.slice(2)])`."],"exampleFix":"// before\nimport { parseCLI } from 'vitest/node'\nparseCLI('run --reporter=dot')\n\n// after\nparseCLI('vitest run --reporter=dot')\n// or\nparseCLI(['vitest', 'run', '--reporter=dot'])","handlingStrategy":"validation","validationCode":"function toVitestArgv(argv: string | string[]): string[] {\n  const arr = typeof argv === 'string' ? argv.split(' ') : argv\n  return arr[0] === 'vitest' ? arr : ['vitest', ...arr]\n}\n\nconst { filter, options } = parseCLI(toVitestArgv(userArgv))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When building argv programmatically, always prepend the binary name.","Keep `parseCLI` calls behind a small wrapper that normalizes argv.","Document that `parseCLI` expects the `vitest` token at index 0."],"tags":["cli","parsecli","argv","programmatic-api"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}