Loading workspace insights... Statistics interval
7 days30 daysLatest CI Pipeline Executions
32319ed1 fix(core): support tuple validation when schema `items` is an array (JSON Schema draft 07) (#34636)
`validateProperty` in `params.ts` did not handle the case where `items`
is an array — the JSON Schema draft 07 tuple validation form. This
caused false validation failures for schemas like Angular's
`@angular/build:unit-test`, which uses tuple `items` to type reporter
configurations:
```json
{
"type": "array",
"minItems": 1,
"maxItems": 2,
"items": [
{ "anyOf": [{ "type": "string" }, { "enum": ["junit", "html", ...] }] },
{ "type": "object" }
]
}
```
Options like `"reporters": [["junit", {"suiteName": "MyApp"}]]` would
incorrectly fail validation with _"Property 'reporters' does not match
the schema"_.
## Changes
- **`validateProperty`**: when `schema.items` is an array, validates
each element against its positional schema instead of passing the whole
array as a schema
- **`minItems`/`maxItems` enforcement**: array length is now validated
against `minItems` and `maxItems` constraints when present
- **`additionalItems` support**: rejects extra items when
`additionalItems: false`; validates against the `additionalItems` schema
when present; otherwise allows additional items (spec-compliant default)
- **`PropertyDescription` type**: added `minItems`, `maxItems`,
`additionalItems` fields; narrowed `items` from `any` to
`PropertyDescription | PropertyDescription[]`
- **Type guards**: added guards in `coerceType` and
`getPromptsForSchema` where `items.enum` was accessed without accounting
for the array form
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Schema validation fails when `items` is a
list.</issue_title>
> <issue_description>### Current Behavior
>
> In JSON Schema draft 07 (2018), the `"items"` property can be a list
and must be validated using tuple validation.
>
> The `validateProperty` util in `packages/nx/src/utils/params.ts`
currently does not support this, causing validation to fail with the
error that the property does not match the schema (but it does).
>
> ### Expected Behavior
>
> A schema using JSON Schema draft 07 like
https://github.com/angular/angular-cli/blob/15794dc101fffd49818545c4ab015a3bf238b14a/packages/angular/build/src/builders/unit-test/schema.json
must be successfully parsed by the NX parser.
>
> OR
>
> The parser must give a clear error message that it does not support
the given schema.
>
> ### GitHub Repo
>
> https://github.com/Ionaru/schema7fail
>
> ### Steps to Reproduce
>
> In https://github.com/Ionaru/schema7fail:
>
> 1. Run `npm install`
> 2. Run `nx test my-app`
>
> ---
>
> Clean repro:
>
> 1. Create an NX project with an Angular application
> 2. In `project.json` add:
> ```json
> "test": {
> "executor": "@angular/build:unit-test",
> "options": {
> "reporters": [["junit", {"suiteName": "MyApp"}]]
> }
> }
> ```
> 3. Run `nx test <app_name>`
>
> ### Nx Report
>
> ```shell
> Node : 24.14.0
> OS : win32-x64
> Native Target : x86_64-windows
> npm : 11.11.0
>
> nx : 22.3.3
> @nx/js : 22.3.3
> @nx/eslint : 22.3.3
> @nx/workspace : 22.3.3
> @nx/angular : 22.3.3
> @nx/devkit : 22.3.3
> @nx/eslint-plugin : 22.3.3
> @nx/module-federation : 22.3.3
> @nx/playwright : 22.3.3
> @nx/plugin : 22.3.3
> @nx/rspack : 22.3.3
> @nx/vite : 22.3.3
> @nx/vitest : 22.3.3
> @nx/web : 22.3.3
> @nx/webpack : 22.3.3
> typescript : 5.9.3
> ```
>
> ### Failure Logs
>
> ```shell
> NX Property 'reporters' does not match the schema.
> {
> "oneOf": [
> {
> "anyOf": [
> {
> "type": "string"
> },
> {
> "enum": [
> "default",
> "verbose",
> "dots",
> "json",
> "junit",
> "tap",
> "tap-flat",
> "html"
> ]
> }
> ]
> },
> {
> "type": "array",
> "minItems": 1,
> "maxItems": 2,
> "items": [
> {
> "anyOf": [
> {
> "type": "string"
> },
> {
> "enum": [
> "default",
> "verbose",
> "dots",
> "json",
> "junit",
> "tap",
> "tap-flat",
> "html"
> ]
> }
> ]
> },
> {
> "type": "object"
> }
> ]
> }
> ]
> }'
> ```
>
> ### Package Manager Version
>
> _No response_
>
> ### Operating System
>
> - [x] macOS
> - [x] Linux
> - [x] Windows
> - [ ] Other (Please specify)
>
> ### Additional Information
>
> Linked to
https://github.com/angular/angular-cli/issues/32618</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes nrwl/nx#34631
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/nrwl/nx/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com> c89dd93e fix(core): resolve false positive loop detection when running with Bun (#34640)
Bun includes extra consecutive async frames for async functions in call
stacks, causing `preventRecursionInGraphConstruction` to falsely detect
a recursive loop during normal project graph construction.
## Root Cause
`preventRecursionInGraphConstruction` uses `getCallSites().slice(2)` to
skip the top 2 frames (itself +
`buildProjectGraphAndSourceMapsWithoutDaemon`), then checks if
`buildProjectGraphAndSourceMapsWithoutDaemon` appears again in the
remaining frames.
In Bun, `buildProjectGraphAndSourceMapsWithoutDaemon` appears **twice
consecutively** due to async frame duplication — leaving one occurrence
after the slice, which incorrectly triggers the loop error.
**Node call stack (after `slice(2)`):**
```
#0 createProjectGraphAndSourceMapsAsync ← clean
#1 createProjectGraphAsync
#2 runOne
```
**Bun call stack (after `slice(2)`):**
```
#0 buildProjectGraphAndSourceMapsWithoutDaemon ← false positive!
#1 createProjectGraphAndSourceMapsAsync
#2 createProjectGraphAndSourceMapsAsync ← Bun duplicates async frames
#3 createProjectGraphAsync
```
## Fix
Since the call stack recursion check does not work reliably under Bun,
`preventRecursionInGraphConstruction` now returns early when running
under Bun, detected via `'Bun' in globalThis` — consistent with the
existing Bun runtime detection pattern used elsewhere in the codebase
(e.g., `isolated-plugin.ts`). The original `slice(2)` logic is preserved
unchanged for Node.js and other runtimes.
```ts
export function preventRecursionInGraphConstruction() {
// Bun's async stack traces include extra frames that cause false positives in the
// recursion check below, so we skip the check when running under Bun.
if ('Bun' in globalThis) {
return;
}
// ... existing Node.js check ...
}
```
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
----
*This section details on the original issue you should resolve*
<issue_title>getCallSites output differs between Node and Bun triggering
loop detection</issue_title>
<issue_description>### Current Behavior
Hey team,
I am trying to use Bun (1.3.5) instead of Node (v22.17.0) for running Nx
(v22.1.3) and bumped into the following error:
Command:
```bash
bunx --bun nx run api:build
```
Error:
```
NX Project graph construction cannot be performed due to a loop detected in the call stack. This can happen if 'createProjectGraphAsync' is called directly or indirectly during project graph construction.
To avoid this, you can add a check against "global.NX_GRAPH_CREATION" before calling "createProjectGraphAsync".
Call stack:
buildProjectGraphAndSourceMapsWithoutDaemon (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:81:62)
createProjectGraphAndSourceMapsAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:274:31)
createProjectGraphAndSourceMapsAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:225:53)
createProjectGraphAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:222:45)
createProjectGraphAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:205:40)
runOne (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/command-line/run/run-one.js:23:52)
runOne (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/command-line/run/run-one.js:16:23)
Pass --verbose to see the stacktrace.
```
After some digging I found that the stack trace produced by
https://github.com/nrwl/nx/blob/691bb320ce1e9cc2872e1a1b364d3fdeb9e1ad0e/packages/nx/src/utils/call-sites.ts
differs between Node and Bun. When
https://github.com/nrwl/nx/blob/691bb320ce1e9cc2872e1a1b364d3fdeb9e1ad0e/packages/nx/src/project-graph/project-graph.ts#L422
is run, the produced function call tracing is:
Node (v22.17.0):
```
nrwl/nx#0 createProjectGraphAndSourceMapsAsync
nrwl/nx#1 createProjectGraphAsync
nrwl/nx#2 runOne
nrwl/nx#3 <anonymous>
nrwl/nx#4 <anonymous>
nrwl/nx#5 handleErrors
nrwl/nx#6 handler
```
Bun (1.3.5):
```
nrwl/nx#0 buildProjectGraphAndSourceMapsWithoutDaemon <- This entry causes Nx to detect a loop
nrwl/nx#1 createProjectGraphAndSourceMapsAsync
nrwl/nx#2 createProjectGraphAndSourceMapsAsync
nrwl/nx#3 createProjectGraphAsync
nrwl/nx#4 createProjectGraphAsync
nrwl/nx#5 runOne
nrwl/nx#6 runOne
```
This is not a Nx bug per-se, but wondering if this falls into the
efforts of supporting Bun into Nx (i.e.
https://nx.dev/blog/nx-19-5-adds-stackblitz-new-features-and-more#bun-and-pnpm-v9-support)?
I will cross post the above into the Bun repo too for input.
### Expected Behavior
Able to execute Nx commands with Bun
### GitHub Repo
_No response_
### Steps to Reproduce
1. Run bunx --bun nx run api:build
### Nx Report
```shell
NX_DAEMON=true bunx --bun nx --disableNxCache --disableRemoteCache --outputStyle dynamic-legacy report 1 ✘ 16:18:00
NX Report complete - copy this into the issue template
Node : 24.3.0
OS : darwin-arm64
Native Target : aarch64-macos
pnpm : 9.6.0
nx : 22.1.3
@nx/js : 22.1.3
@nx/jest : 22.1.3
@nx/eslint : 22.1.3
@nx/workspace : 22.1.3
@nx/cypress : 22.1.3
@nx/devkit : 22.1.3
@nx/esbuild : 22.1.3
@nx/eslint-plugin : 22.1.3
@nx/module-federation : 22.1.3
@nx/nest : 22.1.3
@nx/next : 22.1.3
@nx/node : 22.1.3
@nx/playwright : 22.1.3
@nx/plugin : 22.1.3
@nx/react : 22.1.3
@nx/rollup : 22.1.3
@nx/storybook : 22.1.3
@nx/vite : 22.1.3
@nx/vitest : 22.1.3
@nx/web : 22.1.3
@nx/webpack : 22.1.3
@nx/docker : 22.1.3
nx-cloud : 19.1.0
@nrwl/nx-cloud : 19.1.0
typescript : 5.7.3
---------------------------------------
Registered Plugins:
@nxlv/python
---------------------------------------
Community plu...
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes nrwl/nx#33997
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for you](https://github.com/nrwl/nx/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com> c89dd93e fix(core): resolve false positive loop detection when running with Bun (#34640)
Bun includes extra consecutive async frames for async functions in call
stacks, causing `preventRecursionInGraphConstruction` to falsely detect
a recursive loop during normal project graph construction.
## Root Cause
`preventRecursionInGraphConstruction` uses `getCallSites().slice(2)` to
skip the top 2 frames (itself +
`buildProjectGraphAndSourceMapsWithoutDaemon`), then checks if
`buildProjectGraphAndSourceMapsWithoutDaemon` appears again in the
remaining frames.
In Bun, `buildProjectGraphAndSourceMapsWithoutDaemon` appears **twice
consecutively** due to async frame duplication — leaving one occurrence
after the slice, which incorrectly triggers the loop error.
**Node call stack (after `slice(2)`):**
```
#0 createProjectGraphAndSourceMapsAsync ← clean
#1 createProjectGraphAsync
#2 runOne
```
**Bun call stack (after `slice(2)`):**
```
#0 buildProjectGraphAndSourceMapsWithoutDaemon ← false positive!
#1 createProjectGraphAndSourceMapsAsync
#2 createProjectGraphAndSourceMapsAsync ← Bun duplicates async frames
#3 createProjectGraphAsync
```
## Fix
Since the call stack recursion check does not work reliably under Bun,
`preventRecursionInGraphConstruction` now returns early when running
under Bun, detected via `'Bun' in globalThis` — consistent with the
existing Bun runtime detection pattern used elsewhere in the codebase
(e.g., `isolated-plugin.ts`). The original `slice(2)` logic is preserved
unchanged for Node.js and other runtimes.
```ts
export function preventRecursionInGraphConstruction() {
// Bun's async stack traces include extra frames that cause false positives in the
// recursion check below, so we skip the check when running under Bun.
if ('Bun' in globalThis) {
return;
}
// ... existing Node.js check ...
}
```
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
----
*This section details on the original issue you should resolve*
<issue_title>getCallSites output differs between Node and Bun triggering
loop detection</issue_title>
<issue_description>### Current Behavior
Hey team,
I am trying to use Bun (1.3.5) instead of Node (v22.17.0) for running Nx
(v22.1.3) and bumped into the following error:
Command:
```bash
bunx --bun nx run api:build
```
Error:
```
NX Project graph construction cannot be performed due to a loop detected in the call stack. This can happen if 'createProjectGraphAsync' is called directly or indirectly during project graph construction.
To avoid this, you can add a check against "global.NX_GRAPH_CREATION" before calling "createProjectGraphAsync".
Call stack:
buildProjectGraphAndSourceMapsWithoutDaemon (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:81:62)
createProjectGraphAndSourceMapsAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:274:31)
createProjectGraphAndSourceMapsAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:225:53)
createProjectGraphAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:222:45)
createProjectGraphAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:205:40)
runOne (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/command-line/run/run-one.js:23:52)
runOne (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/command-line/run/run-one.js:16:23)
Pass --verbose to see the stacktrace.
```
After some digging I found that the stack trace produced by
https://github.com/nrwl/nx/blob/691bb320ce1e9cc2872e1a1b364d3fdeb9e1ad0e/packages/nx/src/utils/call-sites.ts
differs between Node and Bun. When
https://github.com/nrwl/nx/blob/691bb320ce1e9cc2872e1a1b364d3fdeb9e1ad0e/packages/nx/src/project-graph/project-graph.ts#L422
is run, the produced function call tracing is:
Node (v22.17.0):
```
nrwl/nx#0 createProjectGraphAndSourceMapsAsync
nrwl/nx#1 createProjectGraphAsync
nrwl/nx#2 runOne
nrwl/nx#3 <anonymous>
nrwl/nx#4 <anonymous>
nrwl/nx#5 handleErrors
nrwl/nx#6 handler
```
Bun (1.3.5):
```
nrwl/nx#0 buildProjectGraphAndSourceMapsWithoutDaemon <- This entry causes Nx to detect a loop
nrwl/nx#1 createProjectGraphAndSourceMapsAsync
nrwl/nx#2 createProjectGraphAndSourceMapsAsync
nrwl/nx#3 createProjectGraphAsync
nrwl/nx#4 createProjectGraphAsync
nrwl/nx#5 runOne
nrwl/nx#6 runOne
```
This is not a Nx bug per-se, but wondering if this falls into the
efforts of supporting Bun into Nx (i.e.
https://nx.dev/blog/nx-19-5-adds-stackblitz-new-features-and-more#bun-and-pnpm-v9-support)?
I will cross post the above into the Bun repo too for input.
### Expected Behavior
Able to execute Nx commands with Bun
### GitHub Repo
_No response_
### Steps to Reproduce
1. Run bunx --bun nx run api:build
### Nx Report
```shell
NX_DAEMON=true bunx --bun nx --disableNxCache --disableRemoteCache --outputStyle dynamic-legacy report 1 ✘ 16:18:00
NX Report complete - copy this into the issue template
Node : 24.3.0
OS : darwin-arm64
Native Target : aarch64-macos
pnpm : 9.6.0
nx : 22.1.3
@nx/js : 22.1.3
@nx/jest : 22.1.3
@nx/eslint : 22.1.3
@nx/workspace : 22.1.3
@nx/cypress : 22.1.3
@nx/devkit : 22.1.3
@nx/esbuild : 22.1.3
@nx/eslint-plugin : 22.1.3
@nx/module-federation : 22.1.3
@nx/nest : 22.1.3
@nx/next : 22.1.3
@nx/node : 22.1.3
@nx/playwright : 22.1.3
@nx/plugin : 22.1.3
@nx/react : 22.1.3
@nx/rollup : 22.1.3
@nx/storybook : 22.1.3
@nx/vite : 22.1.3
@nx/vitest : 22.1.3
@nx/web : 22.1.3
@nx/webpack : 22.1.3
@nx/docker : 22.1.3
nx-cloud : 19.1.0
@nrwl/nx-cloud : 19.1.0
typescript : 5.7.3
---------------------------------------
Registered Plugins:
@nxlv/python
---------------------------------------
Community plu...
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes nrwl/nx#33997
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for you](https://github.com/nrwl/nx/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com> 42f73a52 fix(core): interpolate {projectRoot} and {projectName} in {workspaceRoot} input patterns in native hasher (#34637)
`{projectRoot}` and `{projectName}` tokens inside `{workspaceRoot}/...`
input patterns were silently never substituted in the native Rust
hasher, causing the glob to match zero files and those inputs to be
entirely excluded from the cache hash — a silent cache correctness bug.
## Root Cause
In `gather_self_inputs` (`hash_planner.rs`), workspace filesets (those
starting with `{workspaceRoot}/`) were forwarded as-is to
`HashInstruction::WorkspaceFileSet`. When `globs_from_workspace_globs`
later stripped `{workspaceRoot}/`, the remaining `{projectRoot}/**/*.go`
was matched literally — which never exists on disk.
## Changes
- **`hash_planner.rs`**: Before storing workspace filesets in
`HashInstruction::WorkspaceFileSet`, replace `{projectRoot}` and
`{projectName}` with their actual values from the project graph node.
- **`planner.spec.ts`**: Added a test verifying that a pattern like
`{workspaceRoot}/{projectRoot}/**/*.go` correctly resolves to
`{workspaceRoot}/libs/parent/**/*.go` in the hash plan.
```json
// nx.json — this pattern now works correctly
"namedInputs": {
"goSource": ["{workspaceRoot}/{projectRoot}/**/*.go"]
}
```
This pattern is documented as valid per the [Nx inputs
reference](https://nx.dev/docs/reference/inputs): `{projectRoot}` and
`{projectName}` can appear anywhere after the leading `{workspaceRoot}`.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `repo.gradle.org`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m
-Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en` (dns
block)
> - `staging.nx.app`
> - Triggering command:
`/home/REDACTED/work/_temp/ghcca-node/node/bin/node node
./bin/post-install` (dns block)
> - Triggering command: `/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/home/REDACTED/work/nx/nx/node_modules/.pnpm/nx@22.6.0-beta.5_@swc-node+register@1.11.1_@swc+core@1.15.10_@swc+helpers@0.5.18__@swc+_a827ebc424be037fc154d90301143d4e/node_modules/nx/src/project-graph/plugins/isolation/plugin-worker
/tmp/plugin4368-16-420.890618.sock @nx/enterprise-cloud` (dns block)
> - Triggering command: `/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/home/REDACTED/work/nx/nx/node_modules/.pnpm/nx@22.6.0-beta.5_@swc-node+register@1.11.1_@swc+core@1.15.10_@swc+helpers@0.5.18__@swc+_a827ebc424be037fc154d90301143d4e/node_modules/nx/src/project-graph/plugins/isolation/plugin-worker
/tmp/plugin5770-16-420.874901.sock @nx/enterprise-cloud` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/nrwl/nx/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>{projectRoot} not interpolated inside {workspaceRoot}
input patterns in native hasher</issue_title>
> <issue_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.
>
> ```json
> // nx.json
> "namedInputs": {
> "gosourceUnfiltered": ["{workspaceRoot}/{projectRoot}/**/*.go"]
> }
> ```
>
> ```json
> // 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:
>
> ```rust
> .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](https://nx.dev/docs/reference/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:
>
> ```js
> // In a createNodes plugin, instead of:
> inputs: ["{workspaceRoot}/{projectRoot}/**/*.go"]
> // Use:
> inputs: [`{workspaceRoot}/${actualProjectRoot}/**/*.go`]
> ```
>
> ## Related
>
> - nrwl/nx#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</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes nrwl/nx#34595
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com> 3fc52ead fix(core): resolve input files for targets with defaultConfiguration (#34638)
`nx show target inputs` returns empty results for any target with
`defaultConfiguration` set because
`HashPlanInspector.inspectTaskInputs()` keys results as
`project:target:config` (e.g. `my-app:build:local`), but the lookup was
using `project:target` — a guaranteed miss.
## Changes
- **`packages/nx/src/command-line/show/target.ts`**: In
`resolveInputFiles`, construct the plan lookup key using the explicitly
passed `configuration` first, then fall back to the target's
`defaultConfiguration`:
```ts
const targetConfig = graph.nodes[projectName]?.data?.targets?.[targetName];
const effectiveConfig = configuration ?? targetConfig?.defaultConfiguration;
const taskId = effectiveConfig
? `${projectName}:${targetName}:${effectiveConfig}`
: `${projectName}:${targetName}`;
```
If the computed `taskId` is not found in the hash plan, an error is
thrown instead of silently returning empty results.
- **`showTargetInputsHandler`**: Now extracts the configuration from the
target string (`project:target:config`) or the `-c`/`--configuration`
flag and forwards it to `resolveInputFiles`.
- **`ShowTargetInputsOptions`** (`command-object.ts`): Added
`configuration?: string` so the type correctly reflects the prop.
- **`packages/nx/src/command-line/show/target.spec.ts`**: Added tests
covering:
- Resolving input files when `defaultConfiguration` is set
- Preferring an explicit `configuration` over `defaultConfiguration`
- Throwing when the task ID is not found in the hash plan
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>nx show target inputs returns empty when target has
defaultConfiguration</issue_title>
> <issue_description>## Current Behavior
>
> `nx show target inputs <project>:<target> --json` returns no files for
any target that has a `defaultConfiguration` set (directly or via
`targetDefaults`).
>
> ```bash
> $ nx show target inputs card-api-lambda:build --json
> {
> "project": "card-api-lambda",
> "target": "build"
> }
> # Expected: files array with resolved input files
> ```
>
> The `--check` flag also reports files as not being inputs when they
should be:
>
> ```bash
> $ nx show target inputs card-api-lambda:build --check
packages/card/api/lambda/main.go
> ✗ packages/card/api/lambda/main.go is not an input for
card-api-lambda:build
> ```
>
> Targets **without** `defaultConfiguration` on the same project resolve
correctly:
>
> ```bash
> $ nx show target inputs card-api-lambda:generate-docs --json
> {
> "project": "card-api-lambda",
> "target": "generate-docs",
> "files": [ ".gitignore", "nx.json",
"packages/card/api/lambda/main.go", ... ]
> }
> ```
>
> ## Root Cause
>
> In `packages/nx/src/command-line/show/target.ts`, the
`resolveInputFiles` function constructs the lookup key as:
>
> ```js
> const taskId = `${projectName}:${targetName}`;
> ```
>
> But the native `HashPlanInspector.inspectTaskInputs()` returns results
keyed by the **full task ID including the default configuration**, e.g.
`card-api-lambda:build:local`.
>
> When a target has `defaultConfiguration: "local"`, the plan result is
keyed as `project:target:local`, but the lookup searches for
`project:target` — which doesn't exist — so it falls through to the
empty default `{ files: [], ... }`.
>
> Verified by calling `inspectTaskInputs` directly:
>
> ```
> === build ===
> Task IDs in result: card-api-lambda:generate-docs,
card-api-lambda:build:local
> # lookup for "card-api-lambda:build" → miss → empty
>
> === generate-docs ===
> Task IDs in result: card-api-lambda:generate-docs
> # lookup for "card-api-lambda:generate-docs" → hit → 142 files
> ```
>
> ## Suggested Fix
>
> The lookup key should account for the default configuration:
>
> ```js
> const defaultConfig =
graph.nodes[projectName]?.data?.targets?.[targetName]?.defaultConfiguration;
> const taskId = defaultConfig
> ? `${projectName}:${targetName}:${defaultConfig}`
> : `${projectName}:${targetName}`;
> ```
>
> ## Expected Behavior
>
> `nx show target inputs` should resolve and display input files
regardless of whether the target has a `defaultConfiguration`.
>
> ## Environment
>
> - **Nx version**: 22.6.0-beta.3
> - **OS**: macOS (Darwin 24.6.0)
> - **Node**: v22
> - **Package manager**: pnpm</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes nrwl/nx#34594
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>