{"id":"2919417f59e23d95","repo":"vitest-dev/vitest","slug":"vitest-mergereports-expects-all-paths-in-blob-291941","errorCode":null,"errorMessage":"vitest.mergeReports() expects all paths in \"${blobsDirectory}\" to be files generated by the blob reporter, but \"${filename}\" is not a valid blob file","messagePattern":"vitest\\.mergeReports\\(\\) expects all paths in \"(.+?)\" to be files generated by the blob reporter, but \"(.+?)\" is not a valid blob file","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/reporters/blob.ts","lineNumber":135,"sourceCode":"  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, transformTime] = 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, transformTime }\n  })\n  const blobs = await Promise.all(promises)\n\n  if (!blobs.length) {\n    throw new Error(\n      `vitest.mergeReports() requires at least one blob file in \"${blobsDirectory}\" directory, but none were found`,\n    )\n  }\n\n  const versions = new Set(blobs.map(blob => blob.version))\n  if (versions.size > 1) {\n    throw new Error(\n      `vitest.mergeReports() requires all blob files to be generated by the same Vitest version, received\\n\\n${blobs.map(b => `- \"${b.file}\" uses v${b.version}`).join('\\n')}`,\n    )","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/reporters/blob.ts#L117-L153","documentation":"Thrown as a `TypeError` by `readBlobs` (blob.ts:135) when a file in the merge-reports directory parses via `flatted.parse` but the resulting tuple has no `version` field. A valid blob file is a flatted-stringified array whose first element is the Vitest version that wrote it (see BlobReporter.onTestRunEnd at blob.ts:72-80); a missing version means the file was not produced by the blob reporter.","triggerScenarios":"Manually placing an arbitrary JSON/text file in the merge-reports directory; copying a partial or truncated blob file; a file written by an older/newer format that lacks the version tuple; a file produced by a different tool that happens to be valid JSON but not a blob report.","commonSituations":"Mixing manual JSON outputs into the blob directory; a corrupted or half-written blob file from a crashed run; using the wrong directory as the merge-reports source.","solutions":["Regenerate the blob files by running the blob reporter fresh and merge only those.","Delete any non-blob files from the merge-reports directory before merging.","Ensure the merge-reports directory only contains files written by `BlobReporter` (the default `blob-*.json` outputs)."],"exampleFix":"# remove stale/manual files, then regenerate\nrm -rf ./blob-reports && vitest --reporter=blob\nvitest --merge-reports ./blob-reports","handlingStrategy":"validation","validationCode":"import { readdirSync, readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { parse } from 'flatted'\nfor (const name of readdirSync(blobsDirectory)) {\n  const parsed = parse(readFileSync(resolve(blobsDirectory, name), 'utf-8'))\n  if (!Array.isArray(parsed) || !parsed[0]) throw new Error(`${name} is not a valid blob file`)\n}","typeGuard":"import { parse } from 'flatted'\nconst isBlobFile = (raw: string): boolean => { try { const p = parse(raw); return Array.isArray(p) && !!p[0] } catch { return false } }","tryCatchPattern":null,"preventionTips":["Only place files written by BlobReporter into the merge directory.","Never hand-edit or hand-create blob files.","Regenerate blobs from scratch after format-affecting upgrades."],"tags":["reporter","blob","merge-reports","validation"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}