DEV Community

ANKUSH CHOUDHARY JOHAL
ANKUSH CHOUDHARY JOHAL

Posted on • Originally published at johal.in

War Story: Fixing a Nx 18 Build Cache Issue That Caused Incorrect Deploys

War Story: Fixing a Nx 18 Build Cache Issue That Caused Incorrect Deploys

It was 4:59 PM on a Friday. Our team had just merged a critical feature flag update to the main branch, triggered a production deploy, and headed out for the weekend. Ten minutes later, our on-call alert fired: the production app was showing stale feature flags, breaking core user flows. We rolled back immediately, but the root cause took hours to untangle — and it all came down to a misconfigured Nx 18 build cache.

Our Setup

We run a medium-sized Nx 18 monorepo with 4 frontend applications, 7 shared libraries, and a CI/CD pipeline that uses nx affected --target=build --cache=true to only build projects impacted by new commits. Nx’s task caching had saved us hours of build time over the past year, so we trusted it implicitly — until that Friday.

The Incident

The faulty deploy was for our customer dashboard app, which depends on a shared feature-flags library. We had updated a flag in libs/feature-flags/src/assets/flags.json to enable a new checkout flow, merged to main, and triggered the deploy. Post-deploy checks showed the old flag value was still live, even though the commit was definitely in the production branch.

We first checked the build artifacts pulled from the CI cache: the flags.json file in the dist folder matched the old version, not the new commit. Nx had skipped rebuilding the app, claiming its cache was valid — but the cache was wrong.

Digging Into the Cache

We started by inspecting Nx’s cache behavior. Running nx build app/customer-dashboard --verbose locally showed the same issue: Nx reported the build task was cached, even after we modified flags.json. That meant Nx didn’t detect the file change as a cache invalidation trigger.

Next, we checked our .nxignore file — a common culprit for missing file tracking. Sure enough, when we first set up the feature-flags library months prior, we had accidentally added libs/feature-flags/src/assets to .nxignore to suppress a lint warning for static assets. That single line meant Nx never tracked changes to any file in that directory, so modifying flags.json never invalidated the build cache for the library or its dependent apps.

The Fix

Resolving the issue took three steps:

  1. Removed the erroneous libs/feature-flags/src/assets line from .nxignore to let Nx track changes to static assets in the library.
  2. Cleared the existing Nx cache with nx reset to purge all invalid cached task results.
  3. Updated our CI pipeline to run nx reset before builds as a temporary safeguard, then later added a pre-build step to validate that critical asset directories were not ignored by Nx.

We re-ran the build, verified the new flags.json was present in the artifacts, and deployed successfully. The fix took 20 minutes once we found the root cause — but the investigation taught us hard lessons about cache configuration.

Lessons Learned

  • Never add static asset directories to .nxignore — if you need to exclude them from linting or testing, configure those tools separately instead of ignoring them at the Nx level.
  • Regularly audit your .nxignore and nx.json input configurations, especially after adding new project directories.
  • Add post-build validation steps to your CI pipeline to verify critical files (like feature flags or version manifests) are up to date before deploying.
  • Treat Nx cache misses after expected changes as red flags — don’t assume the cache is always right.

We haven’t had a cache-related deploy failure since. The Friday fire drill was a painful reminder that even tools you trust deeply need regular audits — especially when they control your production deploy artifacts.

Top comments (0)