vitest-dev/vitest · error · TypeError
vi.doMock() expects a string path, but received a ${typeof p
Error message
vi.doMock() expects a string path, but received a ${typeof path} What it means
Thrown by vi.doMock() when its first argument is not a string. The method's TypeScript signature accepts `string | Promise<unknown>` only to keep the compiler happy for dynamic-import-style call sites, but at runtime the mocker needs a resolvable module specifier string. Receiving anything else (undefined, an object, a number) means the call cannot queue a mock and Vitest fails fast with a TypeError rather than silently no-oping.
Source
Thrown at packages/vitest/src/integrations/vi.ts:680
_mocker().getMockContext().callstack,
),
)
: factory,
)
},
unmock(path: string | Promise<unknown>) {
if (typeof path !== 'string') {
throw new TypeError(
`vi.unmock() expects a string path, but received a ${typeof path}`,
)
}
_mocker().queueUnmock(path, getImporter('unmock'))
},
doMock(path: string | Promise<unknown>, factory?: MockOptions | MockFactoryWithHelper) {
if (typeof path !== 'string') {
throw new TypeError(
`vi.doMock() expects a string path, but received a ${typeof path}`,
)
}
const importer = getImporter('doMock')
_mocker().queueMock(
path,
importer,
typeof factory === 'function'
? () =>
factory(() =>
_mocker().importActual(
path,
importer,
_mocker().getMockContext().callstack,
),
)
: factory,
)View on GitHub (pinned to d568f8ce37)
Solutions
- Pass a string module specifier: vi.doMock('./path/to/module', factory).
- If the path comes from a variable, add a runtime check `if (typeof p === 'string')` or assert it before calling doMock.
- Enable strict TypeScript checking on the call site so non-string values are caught at compile time (note the signature is intentionally permissive, so also rely on code review).
- If you intended to pass a Promise from import(), await it or use the string literal directly — doMock does not accept awaited modules either.
Example fix
// before
const mod = await import('./lib')
vi.doMock(mod)
// after
vi.doMock('./lib', () => mockFactory) Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof path !== 'string') {
throw new Error('doMock requires a string module path')
}
vi.doMock(path, factory) Type guard
function isMockPath(path: unknown): path is string {
return typeof path === 'string' && path.length > 0
} Prevention
- Always pass a string literal module specifier to vi.doMock.
- If the path is dynamic, assert/guard its type before the call.
- Review call sites during refactors that touch imports.
When it happens
Trigger: Calling vi.doMock() with a non-string first argument: vi.doMock(undefined), vi.doMock(someModuleObject), vi.doMock(42), or passing a variable whose value is undefined at runtime. Also triggered by spreading arguments incorrectly, e.g. vi.doMock(...someArray) where the first element is not a string.
Common situations: Refactoring an import and forgetting to update the literal path passed to vi.doMock; dynamically computing a module path that resolves to undefined; copy-paste from vi.mock() (which is hoisted and string-only) into a doMock call while reusing a non-string variable; TS loose typing hiding the bug because the union includes Promise<unknown>.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/c7a579bc6e891043.json.
Report an issue: GitHub.