Launch offer: everything is 100% off. Download any skill free, no sign-up. Get the skills
TechFixError fixesBroke after deploy
Broke after deploy

EROFS: read-only file system on Vercel or AWS Lambda

The error in your function logs (the path changes)
Error: EROFS: read-only file system, open '/var/task/data/posts.json'
    errno: -30,
    code: 'EROFS',
    syscall: 'open'
Short answer

Your code writes a file inside the deployed project. Serverless functions can't do that. Save the data to a database or object storage, or use /tmp for throwaway files only.

Why it happens

On your laptop your code can write anywhere in the project folder. Serverless functions run from a read-only copy of your code. Vercel's docs say functions have a read-only file system with a writable /tmp scratch space of up to 500 MB. On AWS Lambda, /tmp is configurable from 512 MB to 10,240 MB, and AWS describes it as temporary and unique to each execution environment.

So a JSON file used as a database, a log file, a cache folder, or uploads saved to ./uploads all fail here. Even writing to /tmp only works for throwaway files: another instance of your function will not see them, and they disappear when the instance does.

Fix it by hand

  1. Find the write. The log names the file. In your code, search for writeFile, appendFile, mkdir, createWriteStream, and upload settings that save to disk (for example multer's diskStorage or a dest: 'uploads/' option).
  2. Decide what the file is. If it must still be there on the next request (user data, uploads, anything people expect to see again), it needs real storage. If it is a scratch file you create and use within one request, /tmp is fine.
  3. For data that must last, move it to a database (Postgres, MySQL, a key-value store) or to object storage (S3, Cloudflare R2, Vercel Blob, Supabase Storage). For uploads, send the file straight to object storage instead of to disk.
  4. For scratch files, write under the system temp folder and clean up:
    import { tmpdir } from 'node:os';
    import { join } from 'node:path';
    const file = join(tmpdir(), 'export.csv'); // /tmp/export.csv on Linux
  5. For logs, use console.log or console.error. Your host collects stdout and stderr, so you don't need a log file.
  6. Redeploy and call the route that failed.

Stop it happening again

Let TechFix do this for you

Broke After Deploy $9

Broke After Deploy finds code that writes files on a server that doesn't keep them, uploads saved to a local folder, and SQLite used as the database on serverless hosting, and shows you the line before you deploy.

  • Checks your project for 37 known causes of "works locally, breaks in production" and runs your production build.
  • Paste the error and it finds the cause in your code, then lists what will break next.
  • Verdict first. Every finding shows the file and line, what it breaks, and the fix as a diff that is applied only with your OK.

Broke After Deploy: how it works, with examples · Install guide

Works with Claude Code, Claude.ai, Cursor, Codex and other agents that read SKILL.md files. No installs, no accounts, works offline. No-questions refund.

Sources (checked 2026-10-13)