vitest-dev/vitest · error · TypeError

vitest.mergeReports() expects all paths in "${blobsDirectory

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

Thrown as a `TypeError` by `readBlobs` (blob.ts:126) when merging reports: Vitest reads every entry in the `--merge-reports` directory and calls `stat()` on each; if an entry is not a regular file (`stats.isFile()` is false, e.g. a subdirectory or a symlink to a directory), it rejects the entry because blob files must be flat files written by the blob reporter.

Source

Thrown at packages/vitest/src/node/reporters/blob.ts:126

    }

    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, transformTime] = 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, transformTime }
  })
  const blobs = await Promise.all(promises)

  if (!blobs.length) {
    throw new Error(

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Point `--merge-reports` at a clean directory that contains only blob JSON files produced by the blob reporter.
  2. Remove subdirectories and non-blob entries from the merge-reports directory.
  3. Use a dedicated output directory for blob reports (set `blob.outputFile` or rely on the default `blob` report dir) so no foreign entries are present.

Example fix

# before
vitest --merge-reports .
# after
vitest --merge-reports ./blob-reports
Defensive patterns

Strategy: validation

Validate before calling

import { readdirSync, statSync } from 'node:fs'
import { resolve } from 'node:path'
const dir = resolve(process.cwd(), blobsDirectory)
const offenders = readdirSync(dir).filter(name => !statSync(resolve(dir, name)).isFile())
if (offenders.length) throw new Error(`Non-file entries in merge dir: ${offenders.join(', ')}`)

Type guard

import { statSync } from 'node:fs'
const isRegularFile = (p: string): boolean => { try { return statSync(p).isFile() } catch { return false } }

Prevention

When it happens

Trigger: Pointing `vitest --merge-reports <dir>` at a directory that contains subdirectories, symlinks to directories, FIFO/socket entries, or `.DS_Store`-like directory metadata. Any non-file entry inside the blobs directory triggers it.

Common situations: Reusing a directory that also holds other artifacts (e.g. `node_modules`, coverage output); a leftover subdirectory from a previous tool; accidentally passing the project root or `.vitest` cache as the merge-reports dir.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/ab015487f91a9b7d.json. Report an issue: GitHub.