Specific bundle chunks repeatedly excluded from production builds despite successful deploys
aalapcshah
PROOP

20 days ago

Project: Klipz 2.0 Branch: manus-sync

Over the past 48 hours, edits to two specific files (client/src/components/AppHeader.tsx and client/src/pages/AdminControlPanel.tsx) have not appeared in the deployed Vite bundle, even though:

  1. Other file changes from the same commits deploy successfully (e.g. client/src/pages/Analytics.tsx, client/src/components/VisualTrainingPanel.tsx — all confirmed live)
  2. GitHub manus-sync HEAD has the correct file contents (verified via raw github.com URL)
  3. Local pnpm run build produces a bundle containing the expected strings
  4. Railway shows deploys completing successfully with new commit SHAs

Evidence:

  • Latest GitHub commit: 43c14223
  • Deployed bundle hash: index-DQeHrJgW.js
  • In the deployed bundle: AppHeaderToolsV2 = NOT FOUND, Activity & Analytics = NOT FOUND, overflow-x:clip = NOT FOUND
  • These strings ARE present in the local build of the same commit

The pattern suggests Railway is caching a specific Vite chunk and excluding the AppHeader-related code from rebuild, while accepting all other file changes. Asking for help identifying which cache layer is involved.

$20 Bounty

8 Replies

Railway
BOT

20 days ago

This thread has been marked as public for community involvement, as it does not contain any sensitive or personal information. Any further activity in this thread will be visible to everyone.

Status changed to Open Railway 20 days ago


shaunclark5649
PRO

20 days ago

Few things I’d check, in the order I’d personally go through them:

  1. The bundle might not actually be new index-DQeHrJgW.js is a content hash. If you’re seeing the same hash across deploys, then nothing changed from Vite’s point of view. Either Railway didn’t rebuild, or you’re being served an old file. Quick check look in the Railway build logs and search for the emitted filename. If the hash in logs is different to what’s live, then it’s a caching issue somewhere (CDN, domain pointing at an old deploy, or even a volume mounted over dist/).
  2. Wrong commit being built That “deployed SHA X” label isn’t always trustworthy if something’s off with webhooks or branch tracking. Stick this in your build command: git rev-parse HEAD && grep -c AppHeaderToolsV2 client/src/components/AppHeader.tsx If grep returns 0 during the build, then the code Railway is building is stale. I’d start looking at watch paths, sparse checkout, or a stuck Nixpacks cache holding onto an old git state
  3. Vite cache being a pain (node_modules/.vite) Nixpacks caches node_modules, and Vite stores its dep cache in there. In rare cases it can serve stale pre-bundled stuff if invalidation doesn’t trigger properly. Force clear it by adding: rm -rf node_modules/.vite dist at the start of your build. If things suddenly fix themselves, that was it.
  4. Case sensitivity issues / duplicate files macOS won’t care about casing, Linux will. If something is importing ./appHeader vs ./AppHeader, Linux might be resolving a completely different file (or an old one). Run: git ls-files | grep -i appheader

If you get more than one result, there’s your problem.

5. Something overwriting the file during build

Worth checking package.json scripts - anything in postinstall, prebuild, or using patch-package. If something is writing into AppHeader.tsx from a cached source, it would look exactly like what you’re seeing.

Most useful thing you can do to narrow it down quickly:

grep -c AppHeaderToolsV2 client/src/components/AppHeader.tsx dist/assets/*.js

That’ll tell you straight away whether the issue is:

  • the source being wrong on the builder
  • the build output being wrong
  • or something serving stale files Once you know which layer it is, you know exactly what to fix.

20 days ago

Hey, to confirm that this isn't a Railway issue, you can tell Railway to purge any kind of caching by running the following CURL command:

curl -x PURGE <url> # make sure to run on the exact path that you are using to check the missing changes

Also, Railway's cache by default is supposed to be two hours, so even if after that period you are still experiencing issues, then it's definitely an issue with how your application is being bundled.


aalapcshah
PROOP

19 days ago

Finalyl able to copy and paste..see my responses to your suggestions in the next thread response. Railway still identified as culprit. Thank you.


shaunclark5649

Few things I’d check, in the order I’d personally go through them: 1. The bundle might not actually be new index-DQeHrJgW.js is a content hash. If you’re seeing the same hash across deploys, then nothing changed from Vite’s point of view. Either Railway didn’t rebuild, or you’re being served an old file. Quick check look in the Railway build logs and search for the emitted filename. If the hash in logs is different to what’s live, then it’s a caching issue somewhere (CDN, domain pointing at an old deploy, or even a volume mounted over dist/). 2. Wrong commit being built That “deployed SHA X” label isn’t always trustworthy if something’s off with webhooks or branch tracking. Stick this in your build command: `git rev-parse HEAD && grep -c AppHeaderToolsV2 client/src/components/AppHeader.tsx` If grep returns 0 during the build, then the code Railway is building is stale. I’d start looking at watch paths, sparse checkout, or a stuck Nixpacks cache holding onto an old git state 3. Vite cache being a pain (node\_modules/.vite) Nixpacks caches node\_modules, and Vite stores its dep cache in there. In rare cases it can serve stale pre-bundled stuff if invalidation doesn’t trigger properly. Force clear it by adding: `rm -rf node_modules/.vite dist` at the start of your build. If things suddenly fix themselves, that was it. 4. Case sensitivity issues / duplicate files macOS won’t care about casing, Linux will. If something is importing ./appHeader vs ./AppHeader, Linux might be resolving a completely different file (or an old one). Run: `git ls-files | grep -i appheader` If you get more than one result, there’s your problem. 5. Something overwriting the file during build Worth checking package.json scripts - anything in postinstall, prebuild, or using patch-package. If something is writing into AppHeader.tsx from a cached source, it would look exactly like what you’re seeing. Most useful thing you can do to narrow it down quickly: `grep -c AppHeaderToolsV2 client/src/components/AppHeader.tsx dist/assets/*.js` That’ll tell you straight away whether the issue is: * the source being wrong on the builder * the build output being wrong * or something serving stale files Once you know which layer it is, you know exactly what to fix.

aalapcshah
PROOP

19 days ago

Step1&2—nixpacks.tomldiff(notcommitted):

[phases.build]

-cmds = ["pnpm run build"]

+cmds = [

+ "rm -rf node_modules/.vite dist",

+ "git rev-parse HEAD && grep -c AppHeaderToolsV2

client/src/components/AppHeader.tsx",

+ "pnpm run build"

+]

Step3—gitls-filescasecheck:

client/src/components/AppHeader.tsx

client/src/components/AppHeaderToolsV2.tsx

Two distinct files, not a case-sensitivity collision. AppHeaderToolsV2.tsx is

the real component that AppHeader.tsx imports. Not the bug.

Step4—postinstall/prebuild/patch-package:

No output — none present. Clean.

Step5—localbuild+grep:

- Source (AppHeader.tsx): 2 occurrences of AppHeaderToolsV2 (import + JSX

usage)

- Dist assets: 0 occurrences

The 0 in dist is expected — Vite minifies and mangles component names, so

AppHeaderToolsV2 doesn't survive as a string literal in the bundle. This is

normal. The meaningful signal is the bundlehash: local build produces

index-CAwXkd-0.js, while Railway production is still serving Aj9pCmwc. That

confirms local source is correct and Railway is the problem.


passos

Hey, to confirm that this isn't a Railway issue, you can tell Railway to purge any kind of caching by running the following CURL command: ``` curl -x PURGE <url> # make sure to run on the exact path that you are using to check the missing changes ``` Also, Railway's cache by default is supposed to be two hours, so even if after that period you are still experiencing issues, then it's definitely an issue with how your application is being bundled.

aalapcshah
PROOP

19 days ago

Hi, thanks for the suggestion. We ran curl -X PURGE (your message had a lowercase -x which is curl's proxy flag — -X PURGE for the HTTP method works) on both https://klipz.shahrx.com/ and https://klipz.shahrx.com/index.html. The page returned successfully but still references the same stale bundle: /assets/index-Aj9pCmwc.js.

We waited well past the 2-hour cache window. Stale bundle persists.

Diagnostic results that point this back to the Railway side:

  1. Local pnpm build produces index-CAwXkd-0.js (different content hash). Source code is current.
  2. Latest Railway build log shows Vite ran fresh and wrote dist/public/assets/index-Aj9pCmwc.js — same hash that's been deployed for 48+ hours. Vite cannot produce identical content hashes from genuinely different source unless it's being fed the same source content.
  3. We verified production bundle content with curl https://klipz.shahrx.com/assets/index-Aj9pCmwc.js > prod.js && grep -c "Visual Training" prod.js → returns 0. The string "Visual Training" was added 50+ commits ago to our codebase. The deployed bundle predates that commit despite Railway showing successful builds for every commit since.
  4. GitHub HEAD on the watched branch (manus-sync) matches our local HEAD at d883a4fc. There is no upstream/local divergence.
  5. Railpack-v0.23.0, Node 22.22.2, single replica in us-west2, custom domain klipz.shahrx.com.

It looks like Railway's build is checking out fresh source and running Vite, but the deployed dist/public/ directory is being restored from an older cached layer at deploy time, overwriting the fresh build output. We've tried clearing Vite cache (rm -rf node_modules/.vite dist) but that command fails on Railway's cache-mounted node_modules with "Device or resource busy."

Can you check:

  • Whether there's a way to clear the build cache for our service from your end?
  • Whether dist/public is being persisted across builds via a layer cache that we can't see or control?
  • Whether the deploy step is restoring an old image rather than using the build output from the most recent successful build?

Service URL: https://railway.com/project/9caee213-b888-4338-b24f-ba10fb..


aalapcshah
PROOP

19 days ago

Quick update on what we've tested today after your curl -X PURGE suggestion:

Cache purge result: Ran curl -X PURGE on https://klipz.shahrx.com/ and /index.html — succeeded but production HTML still references the same stale bundle path /assets/index-Aj9pCmwc.js. We've waited well past the 2-hour cache window. CDN caching ruled out — confirmed via curl with cache-busting query strings and Cache-Control: no-cache headers (all returned identical MD5).

Build is fresh, content is stale: Response headers on the deployed bundle show last-modified: Sun, 03 May 2026 17:03:18 GMT — matches today's build timestamp. Railway IS writing a new file at deploy time. But that file's contents don't include code we added 50+ commits ago. Specifically: curl https://klipz.shahrx.com/assets/index-Aj9pCmwc.js | grep -c "training_labels" returns 0, even though that string is in our committed source code.

Local vs Railway hash divergence: Same git commit, same Vite version, different output filenames:

  • Local (Node v25.8.1): index-CAwXkd-0.js
  • Railway (Node v22.22.2): index-Aj9pCmwc.js

Same Vite hashing the same source content shouldn't produce different filenames just from a Node version delta. We suspect Railway is checking out a different SHA than what's at the GitHub HEAD of the watched branch.

Verified GitHub state: Latest commit on manus-sync is 68e71fcb. git diff HEAD origin/manus-sync returns nothing — local and remote are identical. Branch protection isn't blocking pushes.

Workaround attempted — failed: Tried renaming the Vite output directory from dist/public to dist/client-2026 to force Railway to write new files at a path with no cached version to restore. Railway's build log confirms it wrote to the new path with the same Aj9pCmwc filename, but the served bundle still has none of the recent code (verified with multiple substring checks against committed source).

What's currently being tested: We've added a unique tracer string to package.json"name" field to definitively confirm whether Railway is building our latest commit or a cached older snapshot. Will follow up with that result shortly.

Things we've ruled out on our end:

  • Build cache: dist/ is in .gitignore, no leftover artifacts
  • Postinstall scripts: removed
  • rm -rf node_modules/.vite (your node_modules mount can't be deleted from inside the container — fails with "Device or resource busy")
  • Local repo state: clean, no uncommitted changes that would affect builds
  • Browser/SW caching: cleared via DevTools and confirmed via direct curl

Project info:

  • Service: Klipz-2.0
  • Branch: manus-sync
  • Region: us-west2
  • Node: 22.22.2 (Railpack default)
  • Custom domain: klipz.shahrx.com
  • Replica count: 1

Can you check on your end whether the build container is checking out a SHA other than 68e71fcb for our recent deploys? Or whether there's a layer cache being restored at deploy time that's overwriting our fresh build output?


aalapcshah
PROOP

19 days ago

Definitive evidence Railway is building from a stale SHA:

We added a unique tracer string to package.json's name field: "klipz-deployment-test-68e71fcb". This was committed and pushed to manus-sync (verified at https://github.com/ASVentures/Klipz-2.0/blob/manus-sync/package.json — the string is there).

Railway showed a successful build and deploy after the push. We then ran:

curl -s https://klipz.shahrx.com/assets/index-Aj9pCmwc.js | grep -c "klipz-deployment-test-68e71fcb"

Result: 0

The string our latest commit added is not in the bundle Railway just claimed to build. Vite would have inlined that string into the output during production build (it's referenced via package.json metadata). The fact that it's absent means Railway built from a SHA that predates that commit — even though Railway's UI shows the deploy as "active" with the latest commit message.

GitHub branch state confirmed clean: git diff HEAD origin/manus-sync returns nothing. Local and origin/manus-sync are byte-identical at SHA <insert-current-HEAD-sha>.

This appears to be either:

  1. Railway's GitHub webhook is firing builds against a cached/older SHA
  2. Build container is using a stale cached checkout instead of pulling fresh source from GitHub
  3. Deploy step is restoring an older container image instead of using the new build output

Project: Klipz-2.0

Branch: manus-sync

Region: us-west2

Need someone on your team to investigate. We've exhausted what we can do from the user side.


aalapcshah

**Definitive evidence Railway is building from a stale SHA:** We added a unique tracer string to `package.json`'s `name` field: `"klipz-deployment-test-68e71fcb"`. This was committed and pushed to `manus-sync` (verified at <https://github.com/ASVentures/Klipz-2.0/blob/manus-sync/package.json> — the string is there). Railway showed a successful build and deploy after the push. We then ran: ``` curl -s https://klipz.shahrx.com/assets/index-Aj9pCmwc.js | grep -c "klipz-deployment-test-68e71fcb" ``` Result: **0** The string our latest commit added is not in the bundle Railway just claimed to build. Vite would have inlined that string into the output during production build (it's referenced via package.json metadata). The fact that it's absent means Railway built from a SHA that predates that commit — even though Railway's UI shows the deploy as "active" with the latest commit message. GitHub branch state confirmed clean: `git diff HEAD origin/manus-sync` returns nothing. Local and origin/manus-sync are byte-identical at SHA `<insert-current-HEAD-sha>`. This appears to be either: 1. Railway's GitHub webhook is firing builds against a cached/older SHA 2. Build container is using a stale cached checkout instead of pulling fresh source from GitHub 3. Deploy step is restoring an older container image instead of using the new build output Project: Klipz-2.0 Branch: manus-sync Region: us-west2 Need someone on your team to investigate. We've exhausted what we can do from the user side.

19 days ago

The URL "https://klipz.shahrx.com/assets/index-Aj9pCmwc.js" does not even exist anymore and instead returns an HTML page (the asset is .js file). There are two possibilities that confirm this isn't Railway's fault:

Either you mistakenly believed the index-Aj9pCmwc.js file still exists based on status code alone and weren't checking if it was returning a valid JavaScript file, or Vite has changed the filename to a different hash, which confirms the build is changing and rules out the build cache theory.

A few things that I would recommend doing:

1. Migrate to Railpack, as Nixpacks has been deprecated for a while. Changing to Railpack will ensure a new build without any sort of cache as it isn't at all related to Nixpacks.

2. Make sure that your service settings are using the right branch.

3. Make sure that Railway is picking up your changes via commit hash. You can run railway deployment list --json --limit 2 to check the two most recent deployments and the commit hash Railway picked up.

4. If Railway ever caches any build/layer, it will be shown in the build logs as cached (the same output as Docker's buildkit when it caches a layer). You can use either the CLI or the dashboard to check this information.

5. And lastly, check if you are not using https://docs.railway.com/builds/skipped-builds as that can cause issues sometimes with build cache.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...