Skip to content

fix: improve exhaustive dependencies detection#10258

Open
Newbie012 wants to merge 2 commits intomainfrom
fix-improve-exhaustive-dependencies-detection
Open

fix: improve exhaustive dependencies detection#10258
Newbie012 wants to merge 2 commits intomainfrom
fix-improve-exhaustive-dependencies-detection

Conversation

@Newbie012
Copy link
Collaborator

@Newbie012 Newbie012 commented Mar 11, 2026

🎯 Changes

I updated the lint rule exhaustive-deps so it now catches dependencies used inside nested queryFn callbacks/control flow, and it no longer reports false positives when those dependencies are already encoded in "complex" queryKey expressions.

// 🔴 Before: false negative, no lint error.
// 🟢 After: reports "The following dependencies are missing in your queryKey: id".
useQuery({
  queryKey: ['todo'],
  queryFn: () => Promise.resolve().then(() => id),
})
// 🔴 Before: false positive, reported "The following dependencies are missing in your queryKey: cond, a, b".
// 🟢 After: valid, no exhaustive-deps error.
useQuery({
  queryKey: ['todo', cond ? a : b],
  queryFn: () => (cond ? a : b),
})

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes

    • Fixed exhaustive-deps rule to properly detect dependencies used in nested queryFn callbacks and control flow constructs (then/catch, try/catch/finally).
    • Improved handling of complex queryKey expressions to reduce false positives.
  • Tests

    • Expanded test coverage for various queryKey formations and missing dependency scenarios.

@changeset-bot
Copy link

changeset-bot bot commented Mar 11, 2026

🦋 Changeset detected

Latest commit: f643d72

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tanstack/eslint-plugin-query Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Newbie012 Newbie012 changed the title Fix improve exhaustive dependencies detection fix: improve exhaustive dependencies detection Mar 11, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

This pull request enhances the exhaustive-deps ESLint rule to improve dependency detection in queryFn callbacks and complex queryKey expressions. The fix introduces utility functions to recursively collect dependencies from queryKey nodes and their nested structures, while refactoring the main rule logic to leverage these utilities for more accurate missing dependency identification.

Changes

Cohort / File(s) Summary
Release Metadata
.changeset/perky-seas-flash.md
Introduces changeset entry documenting a patch release for the exhaustive-deps fix.
Test Suite
packages/eslint-plugin-query/src/__tests__/exhaustive-deps.test.ts
Expands test coverage significantly with new valid cases for chained queryKeyFactory usage, conditional expressions in queryKey, and Vue-specific scenarios. Adds invalid cases for missing dependencies in nested callbacks, shadowed locals, and complex queryKey formations.
Core Rule Logic
packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.rule.ts
Refactors dependency detection to use new collectQueryKeyDeps utility instead of manual extraction, improving handling of complex queryKey structures and nested dependencies.
Utility Functions
packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.utils.ts
Introduces three new public utilities: collectQueryKeyDeps for recursive dependency extraction from queryKey nodes, isNode type guard, and collectExternalRefsInFunction for gathering external references within function scopes.
AST Utilities
packages/eslint-plugin-query/src/utils/ast-utils.ts
Enhances getExternalRefs with recursive scope traversal via new collectReferences helper to capture references from nested child scopes, enabling deeper dependency detection.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hops through queryKeys with care,
Deps nested deep, now found everywhere,
Scope chains unwind, no false alarms,
The linter's grip grows strong with arms,
Test cases bloom, from branch to root! 🌱

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description follows the template structure with completed sections (Changes, Checklist, Release Impact), provides concrete examples of before/after behavior, and demonstrates testing and changeset creation.
Title check ✅ Passed The title 'fix: improve exhaustive dependencies detection' directly and clearly summarizes the main change of improving the exhaustive-deps lint rule to better detect dependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-improve-exhaustive-dependencies-detection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Mar 11, 2026

View your CI Pipeline Execution ↗ for commit f643d72

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 1m 1s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-11 08:06:52 UTC

@TanStack TanStack deleted a comment from chatgpt-codex-connector bot Mar 11, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 11, 2026

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@10258

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@10258

@tanstack/preact-query

npm i https://pkg.pr.new/@tanstack/preact-query@10258

@tanstack/preact-query-devtools

npm i https://pkg.pr.new/@tanstack/preact-query-devtools@10258

@tanstack/preact-query-persist-client

npm i https://pkg.pr.new/@tanstack/preact-query-persist-client@10258

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@10258

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@10258

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@10258

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@10258

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@10258

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@10258

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@10258

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@10258

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@10258

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@10258

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@10258

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@10258

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@10258

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@10258

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@10258

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@10258

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@10258

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@10258

commit: 4b75adc

@github-actions
Copy link
Contributor

size-limit report 📦

Path Size
react full 11.92 KB (0%)
react minimal 8.95 KB (0%)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.utils.ts (1)

140-140: Consider using braces to silence the static analysis warning.

The static analysis tool flags this line because the arrow function implicitly returns the result of visit(). While visit() returns void, using braces makes the intent clearer and satisfies the linter.

🔧 Suggested fix
-          node.arguments.forEach((argument) => visit(argument))
+          node.arguments.forEach((argument) => { visit(argument) })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.utils.ts`
at line 140, The forEach callback currently uses an implicit return in the line
node.arguments.forEach((argument) => visit(argument)); change the arrow function
to use a block body to make the intent explicit (e.g., (argument) => {
visit(argument); }) so the static analysis warning is silenced; locate the call
site using node.arguments.forEach and the visit function in
exhaustive-deps.utils.ts and replace the implicit-return arrow with a braced
body.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.utils.ts`:
- Line 140: The forEach callback currently uses an implicit return in the line
node.arguments.forEach((argument) => visit(argument)); change the arrow function
to use a block body to make the intent explicit (e.g., (argument) => {
visit(argument); }) so the static analysis warning is silenced; locate the call
site using node.arguments.forEach and the visit function in
exhaustive-deps.utils.ts and replace the implicit-return arrow with a braced
body.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1417dcbd-9beb-4578-a3ee-751ed43e7917

📥 Commits

Reviewing files that changed from the base of the PR and between 67cf8b6 and f643d72.

📒 Files selected for processing (5)
  • .changeset/perky-seas-flash.md
  • packages/eslint-plugin-query/src/__tests__/exhaustive-deps.test.ts
  • packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.rule.ts
  • packages/eslint-plugin-query/src/rules/exhaustive-deps/exhaustive-deps.utils.ts
  • packages/eslint-plugin-query/src/utils/ast-utils.ts

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