vitest-dev/vitest · error · Error
Expected a single value for option
Error message
Expected a single value for option "${command}", received [${received}] What it means
Thrown by the CLI option `transform` when an option declared as a single value (no `array: true`) receives more than one value across the command line. Vitest wraps `cac` and rejects multi-value input for scalar options so that ambiguous invocations fail loudly instead of silently keeping only the last value.
Solutions
- Pass the option exactly once: `--name value` instead of `--name a --name b`.
- If you genuinely need multiple values, switch to the array form of the option (e.g. `--reporters dot --reporters json`) if one exists.
- Inspect the option definition in `cli-config.ts` to confirm whether `array: true` is set; if not, it is scalar by design.
- Quote the value if a shell is splitting it: `--filter "a b"`.
Example fix
// before vitest run --reporter=dot --reporter=json // after (reporters is the array option) vitest run --reporters=dot --reporters=json
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking parseCLI / cac, dedupe scalar flags.
function dedupeScalarFlags(argv: string[]): string[] {
const seen = new Set<string>()
const out: string[] = []
for (let i = 0; i < argv.length; i++) {
const a = argv[i]
const m = a.match(/^--([\w-]+)(?:=(.*))?$/)
if (m) {
if (seen.has(m[1])) continue // keep first occurrence only
seen.add(m[1])
}
out.push(a)
}
return out
} Prevention
- Consult the option definition in cli-config.ts to know which flags accept arrays.
- Pass multi-value inputs via the documented array form (e.g. `--reporters`). not by repeating a scalar.
- Quote shell-expanded values to avoid accidental multi-value splitting.
When it happens
Trigger: Passing the same scalar flag twice (e.g. `--reporter=dot --reporter=json` when `reporter` is not an array option), or an option that expects one argument receiving a comma/space-separated list that `cac` splits into an array. The check is `!option.array && Array.isArray(value)`.
Common situations: Copy-pasting CLI flags from a script that already set the option; assuming an option accepts repeats because a sibling option does (`reporters` is `array: true` while `reporter` historically was not); shell expansion turning a glob into multiple args for a scalar flag.
Related errors
- Unexpected value for --expect.poll
- Unexpected value for --expect
- Unexpected value "--silent=
- "browser.instances" was set in the config, but the array is…
- --cache.dir is deprecated
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/b58a53863704ddf6.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/node/cli/cac.ts:23
import cac from 'cac'
import { normalize } from 'pathe'
import { disableDefaultColors } from 'tinyrainbow'
import { version } from '../../../package.json' with { type: 'json' }
import { isAgent, isForceColor } from '../../utils/env'
import { cliOptionsConfig, collectCliOptionsConfig } from './cli-config'
import { setupTabCompletions } from './completions'
function addCommand(cli: CAC | Command, name: string, option: CLIOption<any>) {
const commandName = option.alias || name
let command = option.shorthand ? `-${option.shorthand}, --${commandName}` : `--${commandName}`
if ('argument' in option) {
command += ` ${option.argument}`
}
function transform(value: unknown) {
if (!option.array && Array.isArray(value)) {
const received = value.map(s => typeof s === 'string' ? `"${s}"` : s).join(', ')
throw new Error(
`Expected a single value for option "${command}", received [${received}]`,
)
}
value = removeQuotes(value)
if (option.transform) {
return option.transform(value)
}
if (option.array) {
return toArray(value)
}
if (option.normalize) {
return normalize(String(value))
}
return value
}
const hasSubcommands = 'subcommands' in option && option.subcommands
View on GitHub (pinned to 1fa9837ec2)