vitest-dev/vitest · error · TypeError
vitest.mergeReports() expects all paths in
Error message
vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a file What it means
`vitest.mergeReports()` reads every entry in the blobs directory and expects each to be a regular file produced by the blob reporter. If an entry is a subdirectory or other non-file (so `stats.isFile()` is false), the merge aborts with a `TypeError` naming the offending entry.
Solutions
- Inspect the blobs directory and remove any subdirectories.
- Use a dedicated directory that only ever receives blob output.
- Clean the directory (`rm -rf blobs/*`) before each merge-reports run.
Example fix
# before vitest --merge-reports=. # repo root contains node_modules/, .git/ # after vitest --merge-reports=./blobs # dedicated dir, files only
Defensive patterns
Strategy: try-catch
Validate before calling
import { readdir, stat } from 'node:fs/promises'
import { resolve } from 'node:path'
async function assertBlobsDirHasOnlyFiles(dir: string) {
for (const name of await readdir(dir)) {
const s = await stat(resolve(dir, name))
if (!s.isFile()) {
throw new Error(`'${name}' in blobs dir is not a file; remove it before merging.`)
}
}
} Try / catch
try {
await vitest.mergeReports(version, blobsDir, projects)
} catch (e) {
if (e instanceof TypeError && e.message.includes('is not a file')) {
// clean subdirectories from the blobs dir, then retry once
await cleanNonFiles(blobsDir)
return vitest.mergeReports(version, blobsDir, projects)
}
throw e
} Prevention
- Dedicate a directory to blob output only — never reuse a build/output dir.
- Clean the blobs directory before each generate/merge cycle.
When it happens
Trigger: Calling `--merge-reports <dir>` (or `vitest.mergeReports()`) where `readdir(dir)` yields a subdirectory, e.g. a leftover `.git`, `node_modules`, or nested output folder.
Common situations: Pointing `--merge-reports` at the repo root or a directory shared with other build artifacts; a previous run left a subdirectory in the blobs folder.
Related errors
- the blobs in " " were generated by a different version of…
- vitest.mergeReports() expects all paths in
- vitest.mergeReports() requires all blob files to be…
- vitest.mergeReports() requires at least one blob file in
- Blob reporter is not supported in watch mode
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/ab015487f91a9b7d.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/node/reporters/blob.ts:125
}
this.ctx.logger.log('blob report written to', outputFile)
}
}
export async function readBlobs(
currentVersion: string,
blobsDirectory: string,
projectsArray: TestProject[],
): Promise<MergedBlobs> {
// using process.cwd() because --merge-reports can only be used in CLI
const resolvedDir = resolve(process.cwd(), blobsDirectory)
const blobsFiles = await readdir(resolvedDir)
const promises = blobsFiles.map(async (filename) => {
const fullPath = resolve(resolvedDir, filename)
const stats = await stat(fullPath)
if (!stats.isFile()) {
throw new TypeError(
`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a file`,
)
}
const content = await readFile(fullPath, 'utf-8')
const [version, files, errors, coverage, executionTime, environmentModules] = parse(
content,
) as MergeReport
if (!version) {
throw new TypeError(
`vitest.mergeReports() expects all paths in "${blobsDirectory}" to be files generated by the blob reporter, but "${filename}" is not a valid blob file`,
)
}
return { version, files, errors, coverage, file: filename, executionTime, environmentModules }
})
const blobs = await Promise.all(promises)
if (!blobs.length) {
throw new Error(View on GitHub (pinned to 1fa9837ec2)