{"record":{"id":"ab015487f91a9b7d","repo":"vitest-dev/vitest","slug":"vitest-mergereports-expects-all-paths-in-blob","errorCode":null,"errorMessage":"vitest.mergeReports() expects all paths in \"${blobsDirectory}\" to be files generated by the blob reporter, but \"${filename}\" is not a file","messagePattern":"vitest\\.mergeReports\\(\\) expects all paths in \"(.+?)\" to be files generated by the blob reporter, but \"(.+?)\" is not a file","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/reporters/blob.ts","lineNumber":125,"sourceCode":"    }\n\n    this.ctx.logger.log('blob report written to', outputFile)\n  }\n}\n\nexport async function readBlobs(\n  currentVersion: string,\n  blobsDirectory: string,\n  projectsArray: TestProject[],\n): Promise<MergedBlobs> {\n  // using process.cwd() because --merge-reports can only be used in CLI\n  const resolvedDir = resolve(process.cwd(), blobsDirectory)\n  const blobsFiles = await readdir(resolvedDir)\n  const promises = blobsFiles.map(async (filename) => {\n    const fullPath = resolve(resolvedDir, filename)\n    const stats = await stat(fullPath)\n    if (!stats.isFile()) {\n      throw new TypeError(\n        `vitest.mergeReports() expects all paths in \"${blobsDirectory}\" to be files generated by the blob reporter, but \"${filename}\" is not a file`,\n      )\n    }\n    const content = await readFile(fullPath, 'utf-8')\n    const [version, files, errors, coverage, executionTime, environmentModules] = parse(\n      content,\n    ) as MergeReport\n    if (!version) {\n      throw new TypeError(\n        `vitest.mergeReports() expects all paths in \"${blobsDirectory}\" to be files generated by the blob reporter, but \"${filename}\" is not a valid blob file`,\n      )\n    }\n    return { version, files, errors, coverage, file: filename, executionTime, environmentModules }\n  })\n  const blobs = await Promise.all(promises)\n\n  if (!blobs.length) {\n    throw new Error(","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/node/reporters/blob.ts#L107-L143","documentation":"`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.","triggerScenarios":"Calling `--merge-reports <dir>` (or `vitest.mergeReports()`) where `readdir(dir)` yields a subdirectory, e.g. a leftover `.git`, `node_modules`, or nested output folder.","commonSituations":"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.","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."],"exampleFix":"# before\nvitest --merge-reports=.   # repo root contains node_modules/, .git/\n\n# after\nvitest --merge-reports=./blobs   # dedicated dir, files only","handlingStrategy":"try-catch","validationCode":"import { readdir, stat } from 'node:fs/promises'\nimport { resolve } from 'node:path'\n\nasync function assertBlobsDirHasOnlyFiles(dir: string) {\n  for (const name of await readdir(dir)) {\n    const s = await stat(resolve(dir, name))\n    if (!s.isFile()) {\n      throw new Error(`'${name}' in blobs dir is not a file; remove it before merging.`)\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await vitest.mergeReports(version, blobsDir, projects)\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('is not a file')) {\n    // clean subdirectories from the blobs dir, then retry once\n    await cleanNonFiles(blobsDir)\n    return vitest.mergeReports(version, blobsDir, projects)\n  }\n  throw e\n}","preventionTips":["Dedicate a directory to blob output only — never reuse a build/output dir.","Clean the blobs directory before each generate/merge cycle."],"tags":["reporter","blob","merge"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}