Skip to content

fix(linter): do not infer projects from package.json files outside the workspaces - #36510

Draft
FrozenPandaz wants to merge 2 commits into
masterfrom
fix/eslint-plugin-nested-package-json
Draft

fix(linter): do not infer projects from package.json files outside the workspaces#36510
FrozenPandaz wants to merge 2 commits into
masterfrom
fix/eslint-plugin-nested-package-json

Conversation

@FrozenPandaz

Copy link
Copy Markdown
Contributor

Current Behavior

@nx/eslint's inference plugin globs **/package.json, and splitConfigFiles promotes every matching directory to a project root:

const PROJECT_CONFIG_FILENAMES = ['project.json', 'package.json'];

for (const configFile of configFiles) {
  if (PROJECT_CONFIG_FILENAMES.includes(basename(configFile))) {
    projectRoots.add(dirname(configFile));   // <- no workspaces filter
  } else {
    eslintConfigFiles.push(configFile);
  }
}

Nested package.json files are very often markers, not projects — a {"sideEffects": false} beside a bundle, a polyfill directory stub, a workers-site folder. Those have no name, so once promoted they fail the entire graph:

NX   Failed to process project graph.
The projects in the following directories have no name provided:
  - fixtures/legacy-site-app/workers-site
  - packages/unenv-preset/src/runtime/polyfill

The throw is unconditional (project-nodes-manager.ts:268), so one stray marker file takes down the whole workspace — and the error names a directory the user never asked to be a project, which makes it hard to trace back to the linter plugin.

Nx core's own package-json plugin already guards against exactly this in packages/nx/src/plugins/package-json/create-nodes.ts:

if (!isInPackageManagerWorkspaces && !isNextToProjectJson(packageJsonPath)) {
  // Skip if package.json is not part of the package.json workspaces and not next to a project.json.
  return null;
}

@nx/eslint did not.

Expected Behavior

Package.json files are filtered through the package manager's workspaces globs before becoming project roots, reusing the core helpers (buildPackageJsonPatterns / buildPackageJsonWorkspacesMatcher) so the two plugins cannot drift. A package.json sitting next to a project.json is still a project regardless of the globs.

The non-obvious part

The "no workspaces declared" case has to skip the filter entirely:

const isInPackageManagerWorkspaces = patterns.positive.length
  ? buildPackageJsonWorkspacesMatcher(patterns)
  : () => true;

With no workspaces field, buildPackageJsonPatterns returns empty patterns and the matcher rejects everything — including the root package.json of a standalone repo that is the project. Filtering unconditionally deletes the root project and breaks the existing '.' tests. This guard is load-bearing, not defensive.

Validation

Test-first. The new spec was confirmed red against the unfixed plugin, and the failure is precisely the bug:

- Expected  - 0
+ Received  + 1
  Array [
    "packages/a",
+   "packages/a/src/runtime/polyfill",
  ]

Green after the fix. build, test and lint all pass for @nx/eslint (31 tests; the single remaining lint warning is a pre-existing skipped test at plugin.spec.ts:89).

No collateral damage. I captured nx show projects for this repo with and without the change: 145 projects, byte-identical both ways. The fix only removes bogus promotions — it does not drop a single real project. The pre-existing test asserting that a nameless apps/my-app/package.json does get a node (no workspaces declared) still passes, which is the guard above doing its job.

Related Issue(s)

NXC-4746https://linear.app/nxdev/issue/NXC-4746/nxeslint-infers-projects-from-packagejson-files-outside-the-package

The same defect exists in @nx/oxlint and is being fixed on #36491, where it was originally found. This half is independent and ships today, so it is split out here.


Polygraph View session ↗

…e workspaces

The plugin's glob includes `**/package.json`, and `splitConfigFiles` promoted
every matching directory to a project root. Nested marker files — a
`{"sideEffects": false}` next to a bundle, a polyfill directory's stub — have
no `name`, so the whole graph then fails:

    NX   Failed to process project graph.
    The projects in the following directories have no name provided:
      - packages/unenv-preset/src/runtime/polyfill

Filter package.json files through the package manager's workspaces globs, the
same guard Nx core's own package-json plugin applies. A package.json sitting
next to a project.json is still a project regardless of the globs.

When no workspaces are declared the filter is skipped entirely: the patterns
come back empty and the matcher would reject everything, including the root
package.json of a standalone repo that is itself the project.

Verified against this repo: the 145-project graph is identical either way.
@netlify

netlify Bot commented Jul 29, 2026

Copy link
Copy Markdown

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 77fc99d
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/6a6a6044bc3e540008a2fd7f
😎 Deploy Preview https://deploy-preview-36510--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.

@netlify

netlify Bot commented Jul 29, 2026

Copy link
Copy Markdown

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit 77fc99d
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/6a6a6044ffa2c800082ef0f4
😎 Deploy Preview https://deploy-preview-36510--nx-dev.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.

@nx-cloud

nx-cloud Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit fbc14e3

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 9m 47s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 6s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 54s View ↗
nx build workspace-plugin ✅ Succeeded <1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 17s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 5s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-29 20:33:09 UTC

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

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 flaky task in your failed CI:

🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.

Nx Cloud View detailed reasoning in Nx Cloud ↗

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.


🎓 Learn more about Self-Healing CI on nx.dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant