EBUSY build failure persists despite .npmrc workaround in repo
yojake42
HOBBYOP

25 days ago

EBUSY: resource busy or locked, rmdir '/app/apps/web/node_modules/.vite'

happened out of nowhere one day when I pushed, I fully reverted the entire app back to the state before the change that introduced the error, the EBUSY build fails still. I cannot resolve this myself, as the files don't exist when look in the console, the console is hitting the last good built container. This is a railway bug. The build error even exists on other builds in this environment that don't even use vite.

10+ redeploy attempts, same error every time. .npmrc workaround already merged in repo (legacy-peer-deps=true, force=true).

Package-lock.json already regenerated.

This looks like a build environment lock issue, not code-level.

$10 Bounty

3 Replies

Railway
BOT

25 days ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway • 25 days ago


vihanga-himantha
HOBBY

23 days ago

Try this

you must explicitly force Railway to discard the build cache and start fresh.

Open Service Deployments: Navigate to your Railway Dashboard, select your project, and click on the failing Service.

Then

Trigger Cacheless Deploy

Find your latest failed deployment in the history list. Click the three dots (...) next to it, and select Redeploy (without cache).

(Alternatively, press Cmd/Ctrl + K to open the command palette and type "Redeploy without cache".)

If you use the Railway CLI:

You can achieve the same result instantly from your terminal by running:

railway up --detach --no-cache

Watch your deployment logs. You should see Nixpacks explicitly skip the cache restoration step and perform a completely fresh npm install. This will take slightly longer than a normal build, but it will bypass the locked .vite directory.


muhammad-tahir-anis
HOBBY

23 days ago

Had this exact issue on a Railway deploy a few weeks back. It's not your code or your .npmrc, you're right, it's a build cache problem.

What's happening: Railway caches your node_modules layer between builds. Somewhere along the way that cache got into a bad state (probably a build got killed mid write, or Vite's .vite optimizer cache and your install step raced each other). Once that layer's corrupted, every build after inherits the same broken directory state. That's why reverting your code did nothing and why it's showing up on other services that don't even use Vite. legacy-peer-deps and force=true only affect dependency resolution, they can't touch a stale filesystem lock left over from a previous build.

What's worked for me:

  1. Go to the deployment's three dot menu and hit Clear build cache. This fixes it most of the time.
  2. If that option isn't there or doesn't help, delete the service and recreate it from the same repo and env vars. Not elegant but it forces a totally clean build environment.
  3. In the meantime add rm -rf node_modules/.vite as a pre build step in your build command so it doesn't choke on a stale cache.
  4. If you're on Nixpacks, try switching to a Dockerfile build instead. Nixpacks layer caching is probably the actual culprit, and a Dockerfile build skips that whole heuristic.

I'd try clearing the cache first before anything else since this really is a build environment problem on their end, not something you can fix from the repo.


Anonymous
FREE

21 days ago

If this deployment uses Railpack, that exact .vite path points to a specific possibility: a build-cache mount being deleted.

Railpack creates Vite caches at /app/<workspace>/node_modules/.vite. Its cache documentation explicitly says removing a cache directory produces EBUSY, and that these caches are absent from the final image. That explains why checking the last successful runtime container would not show the same directory.

For a targeted check, add this variable to the affected service and trigger a new build:

RAILPACK_DISABLE_CACHES=*

This is Railpack's documented cache-mount control; it leaves layer caching enabled. If the build succeeds, narrow the value to the relevant cache name from the generated plan to restore the other caches.

I checked this with Railpack 0.39.0 and a minimal apps/web Vite workspace: the generated key was vite-apps-web. Setting RAILPACK_DISABLE_CACHES=vite-apps-web removed that mount and preserved the other caches. This was a plan-only check with fixed Node-version lookup, not a container build.

Also inspect the failing build command and its prebuild/workspace scripts for a second npm ci or a command that removes node_modules. npm documents that npm ci removes existing node_modules before installing. Keep dependency installation in the install step and compilation in the build step where possible. Adding rm -rf node_modules/.vite would attempt to remove the same mounted directory; .npmrc dependency-resolution flags cannot change that mount behavior.

This is a specific Railpack workaround to test, not confirmation of the cause in your deployment: the public post does not include its builder/version or complete failing command.

Chandan


Welcome!

Sign in to your Railway account to join the conversation.

Loading...