-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
Current Behavior
When using a {workspaceRoot}/{projectRoot}/**/*.go pattern in target inputs, the {projectRoot} token is not interpolated by the native Rust hash planner. The pattern silently matches zero files, causing the cache hash to exclude those files entirely.
// nx.json
"namedInputs": {
"gosourceUnfiltered": ["{workspaceRoot}/{projectRoot}/**/*.go"]
}// target config
"format": {
"inputs": ["gosourceUnfiltered", { "externalDependencies": [] }]
}The hash plan for this target contains zero .go file inputs:
Task: my-project:format:write
Inputs:
my-project:ProjectConfiguration
my-project:TsConfig
env:NX_CLOUD_ENCRYPTION_KEY
file:nx.json
file:.gitignore
// no .go files!
Root Cause
In the Rust hash planner (hash_planner.rs), fileset inputs are partitioned based on their prefix:
.partition(|file_set| {
file_set.starts_with("{projectRoot}/") || file_set.starts_with("!{projectRoot}/")
});A pattern starting with {workspaceRoot}/ is classified as a workspace fileset. It then flows to hash_workspace_files.rs where {workspaceRoot}/ is stripped via strip_prefix("{workspaceRoot}/"), leaving {projectRoot}/**/*.go. But {projectRoot} is never substituted with the actual project root, so the glob literally tries to match paths starting with {projectRoot}/ — which don't exist.
Expected Behavior
Per the Nx docs on inputs:
{workspaceRoot}should only appear in the beginning of an input but{projectRoot}and{projectName}can be specified later in the input to interpolate the root or name of the project into the input location.
The native hasher should interpolate {projectRoot} (and {projectName}) within {workspaceRoot} patterns before glob matching. After stripping {workspaceRoot}/ and interpolating {projectRoot}, the pattern should become e.g. packages/shared/go/middleware/**/*.go and correctly match files.
Impact
This is a silent cache correctness issue: targets using this pattern appear to work but their cache hash doesn't include the matched files. Changes to those files won't invalidate the cache. There's no warning or error emitted.
Workaround
Use the literal path instead of {projectRoot} inside workspace-level patterns:
// In a createNodes plugin, instead of:
inputs: ["{workspaceRoot}/{projectRoot}/**/*.go"]
// Use:
inputs: [`{workspaceRoot}/${actualProjectRoot}/**/*.go`]Related
- Nested Project Files Excluded from Parent Project Inputs #34225 — Nested Project Files Excluded from Parent Project Inputs (the reason
{workspaceRoot}/{projectRoot}patterns are used in the first place: to bypass project file filtering and include files from nested sub-projects)
Environment
- Nx version: 22.6.0-beta.3
- OS: macOS (Darwin 24.6.0)
- Package manager: pnpm