{"record":{"id":"abec29187310c33f","repo":"vitest-dev/vitest","slug":"couldn-t-write-file-to-fs","errorCode":null,"errorMessage":"Couldn't write file to fs","messagePattern":"Couldn't write file to fs","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser/src/node/commands/screenshotMatcher/index.ts","lineNumber":571,"sourceCode":"    target,\n  })\n\n  return {\n    buffer: screenshot,\n    image: await codec.decode(screenshot, {}),\n  }\n}\n\n/** Writes encoded images to disk, creating parent directories as needed. */\nasync function writeScreenshot(path: string, image: TypedArray, project: TestProject) {\n  try {\n    assertBrowserApiWrite(project, path)\n    assertBrowserFileAccess(project, path)\n    await mkdir(dirname(path), { recursive: true })\n    await writeFile(path, image)\n  }\n  catch (cause) {\n    throw new Error('Couldn\\'t write file to fs', { cause })\n  }\n}\n","sourceCodeStart":553,"sourceCodeEnd":574,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/browser/src/node/commands/screenshotMatcher/index.ts#L553-L574","documentation":"Thrown by writeScreenshot after both assertBrowserApiWrite and assertBrowserFileAccess have already passed, so it indicates a genuine filesystem failure during mkdir(dirname) or writeFile. The original error is preserved on the `cause` property. It is a defensive wrapper that normalizes any low-level FS error (EACCES, ENOSPC, EISDIR, ENOENT for an unresolvable parent) into a single human-readable message.","triggerScenarios":"Calling a screenshot-matcher command (e.g. expect(...).toMatchScreenshot with an output path) where the destination directory cannot be created or the file cannot be written. Concrete causes: read-only filesystem, ENOSPC (disk full), EACCES on the target directory, a path that resolves to an existing directory (EISDIR), or a symbolic-link loop that mkdir cannot resolve.","commonSituations":"Running browser screenshot tests in a sandboxed/CI container with a read-only mount; specifying a screenshot path outside the project root that the OS refuses to create; disk-full CI runners; Windows path with illegal characters; a relative path that resolves to a directory slot already occupied.","solutions":["Inspect err.cause for the real POSIX error code (EACCES/ENOSPC/EISDIR) and address that specifically.","Free disk space or raise the CI runner disk quota if err.cause.code === 'ENOSPC'.","Change the screenshot output path to a writable location inside the project root, or grant write permission to the target directory.","Confirm the path does not point to an existing directory or a file owned by another user.","If running in a container, verify the mounted volume is writable by the Vitest process user."],"exampleFix":"// before\nawait writeFile(path, image)\n// after - surface the real cause and pick a writable, existing parent\ntry {\n  await mkdir(dirname(path), { recursive: true })\n  await writeFile(path, image)\n}\ncatch (cause) {\n  throw new Error(`Couldn't write screenshot to ${path}: ${(cause as NodeJS.ErrnoException).code}`, { cause })\n}","handlingStrategy":"try-catch","validationCode":"import { access, constants } from 'node:fs/promises'\nasync function canWriteTo(dir: string) {\n  try { await access(dir, constants.W_OK); return true } catch { return false }\n}","typeGuard":"function isNodeErrno(e: unknown): e is NodeJS.ErrnoException {\n  return e instanceof Error && typeof (e as NodeJS.ErrnoException).code === 'string'\n}","tryCatchPattern":"try { await browserCommandThatWritesScreenshot(path) }\ncatch (e) {\n  const code = (e as NodeJS.ErrnoException).cause && ((e as any).cause as NodeJS.ErrnoException).code\n  if (code === 'ENOSPC') /* free disk */\n  else if (code === 'EACCES') /* fix perms */\n  else throw e\n}","preventionTips":["Run screenshot tests with a writable, project-rooted output directory.","Surface err.cause.code in CI logs so the real POSIX error is visible.","Assert disk headroom before writing large screenshot batches."],"tags":["filesystem","screenshot","browser","io"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}