Skip to content

Conversation

@AgentEnder
Copy link
Member

Current Behavior

When the Nx daemon returns a cached project graph from memory (without recomputing), it does not write the graph to disk. This creates a cache/daemon mismatch scenario:

  1. Daemon has valid project graph in memory
  2. A non-daemon process (fallback when daemon fails) encounters errors and writes cache to disk with those errors
  3. Parent process gets clean graph from daemon
  4. Forked executor processes read from disk cache which contains errors
  5. The errors cause readProjectGraphCache() to return null (when no minimumComputedAt is provided)
  6. This triggers a misleading "No cached ProjectGraph is available" error instead of surfacing the actual errors

This issue manifests intermittently in CI environments, especially when:

  • Daemon connection timeouts occur
  • Multiple concurrent processes are running (DTE scenarios)
  • File system latency is high

Expected Behavior

The daemon should always write its current project graph to disk whenever it returns it, ensuring the disk cache stays synchronized with the daemon's in-memory cache. This prevents stale or errored caches from persisting when the daemon has a valid graph.

Related Issue(s)

Fixes NXC-3030

Implementation Details

Modified getCachedSerializedProjectGraphPromise() in packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts to write the project graph cache to disk after retrieving the result, even when reusing the in-memory cached graph.

The fix ensures that:

  • Any errored cache written by a non-daemon process gets overwritten by the daemon's valid graph
  • Forked executor processes always read a consistent cache that matches what the daemon served to the parent process
  • Real errors are properly surfaced instead of being hidden by a generic "no cache available" message

🤖 Generated with Claude Code

@AgentEnder AgentEnder requested a review from a team as a code owner October 23, 2025 16:09
@netlify
Copy link

netlify bot commented Oct 23, 2025

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 6312756
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/68fba4df6e23240009a83501
😎 Deploy Preview https://deploy-preview-33217--nx-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel
Copy link

vercel bot commented Oct 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
nx-dev Ready Ready Preview Oct 24, 2025 4:54pm

@nx-cloud
Copy link
Contributor

nx-cloud bot commented Oct 23, 2025

View your CI Pipeline Execution ↗ for commit 6312756

Command Status Duration Result
nx affected --targets=lint,test,test-kt,build,e... ✅ Succeeded 40m 1s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 2m 51s View ↗
nx-cloud record -- nx-cloud conformance:check ✅ Succeeded 10s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-24 16:56:30 UTC

nx-cloud[bot]

This comment was marked as outdated.

Copy link
Collaborator

@FrozenPandaz FrozenPandaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would write cache twice I believe? Can you find where we currently write the cache and see if there's any conditions to remove

Copy link
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a possible root cause for your failed CI:

The failure is classified as 'environment_state' rather than 'code_change' for the following reasons:

The PR diff shows a code change to packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts that adds logic to write the daemon's current graph to disk to keep the cache in sync. This change is specifically designed to prevent stale/errored cache issues.

However, the failing task e2e-dotnet:e2e-ci--src/dotnet-multi-project.test.ts is completely unrelated to the project graph caching logic modified in the diff. The test failures show:

  1. A .NET SDK configuration issue with mutex creation: System.IO.IOException: The system cannot open the device or file specified. : 'NuGet-Migrations'
  2. The error indicates a file system race condition: mkdir("/tmp/.dotnet/shm/session63", AllUsers_ReadWriteExecute) == -1; errno == EEXIST
  3. All three test failures occur before any test logic executes - they fail during the setup phase when trying to create .NET projects
  4. The error spawnSync /bin/sh ENOENT suggests the shell environment is not properly initialized or available

The modified code in the PR deals with Nx's project graph daemon and in-memory caching, which has no relationship to:

  • .NET SDK initialization
  • NuGet package manager configuration
  • File system mutex operations in /tmp/.dotnet/shm/
  • The e2e test framework's ability to spawn shell processes

The failures are occurring in the .NET plugin's e2e tests during environment initialization, not during any code path that would interact with the project graph caching changes. The timing and nature of the failures (file system race conditions, mutex conflicts, missing shell access) point to environmental issues in the CI system rather than a logical consequence of the code changes made in this PR.

A code change would likely not resolve this issue, so no action was taken.

Nx CloudView in Nx Cloud ↗


🎓 To learn more about Self Healing CI, please visit nx.dev

@AgentEnder AgentEnder force-pushed the fix/nxc-3030-daemon-cache-sync branch 2 times, most recently from 2d6c7d1 to 6b3cc9a Compare October 23, 2025 21:27

return result;
} catch (e) {
if (e instanceof DaemonProjectGraphError) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is ever possible.. is it? I'd remove this. writing to the cache above already handles the cases we're seeing I htink.

When the daemon returns a cached project graph from memory, it now
always writes it to disk. This prevents cache/daemon mismatches where
a non-daemon process writes a stale or errored cache that never gets
overwritten by the daemon's valid in-memory graph.

Fixes NXC-3030

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@AgentEnder AgentEnder force-pushed the fix/nxc-3030-daemon-cache-sync branch from 6b3cc9a to 6312756 Compare October 24, 2025 16:10
@FrozenPandaz FrozenPandaz enabled auto-merge (squash) October 24, 2025 16:33
@FrozenPandaz FrozenPandaz merged commit 7021056 into master Oct 24, 2025
19 checks passed
@FrozenPandaz FrozenPandaz deleted the fix/nxc-3030-daemon-cache-sync branch October 24, 2025 16:56
FrozenPandaz pushed a commit that referenced this pull request Oct 27, 2025
…tly (#33217)

## Current Behavior

When the Nx daemon returns a cached project graph from memory (without
recomputing), it does not write the graph to disk. This creates a
cache/daemon mismatch scenario:

1. Daemon has valid project graph in memory
2. A non-daemon process (fallback when daemon fails) encounters errors
and writes cache to disk with those errors
3. Parent process gets clean graph from daemon
4. Forked executor processes read from disk cache which contains errors
5. The errors cause `readProjectGraphCache()` to return `null` (when no
`minimumComputedAt` is provided)
6. This triggers a misleading "No cached ProjectGraph is available"
error instead of surfacing the actual errors

This issue manifests intermittently in CI environments, especially when:
- Daemon connection timeouts occur
- Multiple concurrent processes are running (DTE scenarios)
- File system latency is high

## Expected Behavior

The daemon should always write its current project graph to disk
whenever it returns it, ensuring the disk cache stays synchronized with
the daemon's in-memory cache. This prevents stale or errored caches from
persisting when the daemon has a valid graph.

## Related Issue(s)

Fixes NXC-3030

## Implementation Details

Modified `getCachedSerializedProjectGraphPromise()` in
`packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts`
to write the project graph cache to disk after retrieving the result,
even when reusing the in-memory cached graph.

The fix ensures that:
- Any errored cache written by a non-daemon process gets overwritten by
the daemon's valid graph
- Forked executor processes always read a consistent cache that matches
what the daemon served to the parent process
- Real errors are properly surfaced instead of being hidden by a generic
"no cache available" message

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <[email protected]>
(cherry picked from commit 7021056)
FrozenPandaz pushed a commit that referenced this pull request Oct 27, 2025
…tly (#33217)

## Current Behavior

When the Nx daemon returns a cached project graph from memory (without
recomputing), it does not write the graph to disk. This creates a
cache/daemon mismatch scenario:

1. Daemon has valid project graph in memory
2. A non-daemon process (fallback when daemon fails) encounters errors
and writes cache to disk with those errors
3. Parent process gets clean graph from daemon
4. Forked executor processes read from disk cache which contains errors
5. The errors cause `readProjectGraphCache()` to return `null` (when no
`minimumComputedAt` is provided)
6. This triggers a misleading "No cached ProjectGraph is available"
error instead of surfacing the actual errors

This issue manifests intermittently in CI environments, especially when:
- Daemon connection timeouts occur
- Multiple concurrent processes are running (DTE scenarios)
- File system latency is high

## Expected Behavior

The daemon should always write its current project graph to disk
whenever it returns it, ensuring the disk cache stays synchronized with
the daemon's in-memory cache. This prevents stale or errored caches from
persisting when the daemon has a valid graph.

## Related Issue(s)

Fixes NXC-3030

## Implementation Details

Modified `getCachedSerializedProjectGraphPromise()` in
`packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts`
to write the project graph cache to disk after retrieving the result,
even when reusing the in-memory cached graph.

The fix ensures that:
- Any errored cache written by a non-daemon process gets overwritten by
the daemon's valid graph
- Forked executor processes always read a consistent cache that matches
what the daemon served to the parent process
- Real errors are properly surfaced instead of being hidden by a generic
"no cache available" message

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <[email protected]>
(cherry picked from commit 7021056)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants