vitest-dev/vitest · error · Error
Cannot upload files outside of a test
Error message
Cannot upload files outside of a test
What it means
Thrown by the Playwright upload user-event command when context.testPath is falsy. The upload command resolves file paths relative to the project root and the test file; without a bound test it refuses to read files from disk (also a safety check against arbitrary path uploads outside a test).
Source
Thrown at packages/browser-playwright/src/commands/upload.ts:20
import type { UserEventUploadOptions } from 'vitest/browser'
import type { UserEventCommand } from './utils'
import { assertBrowserFileAccess } from '@vitest/browser'
import { resolve } from 'pathe'
import { getDescribedLocator } from './utils'
export const upload: UserEventCommand<(element: SerializedLocator, files: Array<string | {
name: string
mimeType: string
base64: string
}>, options: UserEventUploadOptions) => void> = async (
context,
selector,
files,
options,
) => {
const testPath = context.testPath
if (!testPath) {
throw new Error(`Cannot upload files outside of a test`)
}
const root = context.project.config.root
const playwrightFiles = files.map((file) => {
if (typeof file === 'string') {
const filepath = resolve(root, file)
assertBrowserFileAccess(context.project, filepath)
return filepath
}
return {
name: file.name,
mimeType: file.mimeType,
buffer: Buffer.from(file.base64, 'base64'),
}
})
await getDescribedLocator(context, selector).setInputFiles(playwrightFiles as string[], options)
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Call page.upload from inside an it/test body so testPath is set.
- Move file-upload logic out of global setup and into the test that triggers the upload.
- For setup-time uploads, drive the <input type=file> via Playwright's setInputFiles directly with absolute paths.
Example fix
// before (setup.ts)
import { page } from '@vitest/browser'
await page.upload(fileInput, ['./fixture.png'])
// after (test file)
import { test } from 'vitest'
import { page } from '@vitest/browser'
test('upload', async () => {
await page.upload(fileInput, ['./fixture.png'])
}) Defensive patterns
Strategy: validation
Validate before calling
if (!context.testPath) {
throw new Error('upload must be called from within a test')
}
await upload(context, selector, files, options) Type guard
function inTestFile(c: BrowserCommandContext): c is BrowserCommandContext & { testPath: string } {
return typeof c.testPath === 'string' && c.testPath.length > 0
} Prevention
- Call page.upload only from it/test bodies.
- Keep shared helpers that use @vitest/browser upload out of node-pool tests.
- For setup uploads, use Playwright setInputFiles directly with absolute paths.
When it happens
Trigger: Calling page.upload(element, files) from global setup, a beforeAll in a non-test module, or any context without a testPath. Also triggered by manually invoking the upload command with a hand-built context.
Common situations: Uploading fixtures from setup files, shared utils imported outside tests, or invoking upload inside worker-scoped hooks that lack a test path.
Related errors
- Cannot take a screenshot without a test path
- Element not found: ${v.element}
- stopChunkTrace cannot be called outside of the test file.
- This command can only be called inside a test file.
- The ${provider.name} provider does not support tracing.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/3881c5a5d26a259d.json.
Report an issue: GitHub.