EACCES, EROFS, ENOSPC, or EBUSY in a container? Filesystem errors that aren't what they look like
Filesystem errors inside a container are misleading, because the error name describes the symptom, not the cause — and the cause is usually the sandbox, not your code. Four you'll actually hit: EACCES, EROFS, ENOSPC, and EBUSY.
EACCES / EROFS: it's the container, not your logic
EACCES 'permission denied' and EROFS 'read-only file system' inside a container almost always trace to the environment:
- UID mismatch. The container process runs as a user that doesn't own the files — works locally where you're the owner, fails in the container. Fix ownership or run as the right UID.
- Read-only mount. The path is mounted read-only (a common hardening default). You're trying to write where writes are disallowed — write to a writable volume (e.g. a tmpfs or a mounted data dir) instead.
ENOSPC: probably not disk space
The classic trap: ENOSPC 'no space left on device' when df shows plenty of space. On Linux it's frequently the inotify watcher limit — a file watcher or bundler exhausted fs.inotify.max_user_watches, and the kernel reports it as ENOSPC. Raise the watcher limit; don't go hunting for disk space that isn't the issue.
EBUSY: resource busy / locked
EBUSY 'resource busy' (or a locked file on Windows) means something else holds the file — a handle still open, a lock not released. It's often transient: retry with a short backoff after the holder releases, rather than failing hard on the first attempt.
For agents touching the filesystem
An agent that treats ENOSPC as "disk full" or EACCES as "my code is wrong" chases the wrong fix. diagnose_infra_error returns the filesystem family and points at the real cause — a watcher limit, a UID/mount issue, or a transient lock:
diagnose_infra_error({error: "ENOSPC no space left on device inotify"})
// → { family: "filesystem",
// fix: "inotify watcher limit, not disk — raise fs.inotify.max_user_watches" }Machine-readable guide: https://snapback.sh/llms.txt · Tool discovery: https://snapback.sh/.well-known/mcp.json · MCP endpoint: https://api.snapback.sh/mcp. Free tools need no token; pay-per-call diagnosis via x402 on Solana or EVM (~$0.0032 USDC).