Skip to content

feat(query-core): add opt-in ignoreUndefinedInKeys filter option#10808

Open
webdevelopersrinu wants to merge 3 commits into
TanStack:mainfrom
webdevelopersrinu:fix/3741-ignore-undefined-in-keys
Open

feat(query-core): add opt-in ignoreUndefinedInKeys filter option#10808
webdevelopersrinu wants to merge 3 commits into
TanStack:mainfrom
webdevelopersrinu:fix/3741-ignore-undefined-in-keys

Conversation

@webdevelopersrinu
Copy link
Copy Markdown

@webdevelopersrinu webdevelopersrinu commented May 26, 2026

Summary

Adds an opt-in ignoreUndefinedInKeys option to QueryFilters and MutationFilters to resolve the long-standing inconsistency between hashKey (strips undefined via JSON.stringify) and partialMatchKey (keeps undefined).

Refs #3741

Background

When a query key contains an object property with value undefined, the cache stores it under a hash that excludes that property — but invalidateQueries cannot match it back when a sibling cache entry has a concrete value for the same property. See #3741 and the closed #4616 for full history.

@TkDodo previously raised the concern that there is no clean non-breaking fix. This PR addresses that by making the new behavior fully opt-in (default false → zero behavior change for existing users).

API

```ts
queryClient.invalidateQueries({
queryKey: [{ entity: 'todos', filter: undefined }],
ignoreUndefinedInKeys: true,
})
```

Also available on MutationFilters.

Design notes

  • Plain objects only. undefined inside arrays is preserved.
  • Recursive. Nested objects strip undefined at every level.
  • Exported PartialMatchKeyOptions type for downstream adapter use.
  • No new option on QueryClient defaults — kept the surface small. Happy to add a global default in a follow-up.

Tests

  • 4 unit tests in utils.test.tsx (broken-case, concrete-value-differ, array preservation, nested recursion).
  • 1 end-to-end test in queryClient.test.tsx exercising invalidateQueries.

All 531 query-core tests pass locally.

Summary by CodeRabbit

  • New Features

    • Added ignoreUndefinedInKeys for query and mutation filters. When enabled, undefined properties in keys are treated as absent during partial matching (applies recursively to nested objects); default behavior remains unchanged.
  • Tests

    • Added regression tests covering invalidate/match behavior with undefined values, nested objects, arrays, and the ignoreUndefinedInKeys toggle.

Review Change Stack

Fixes inconsistency where `hashKey` strips `undefined` object properties
(via `JSON.stringify`) but `partialMatchKey` keeps them, causing
`invalidateQueries({ queryKey: [{ ...filter: undefined }] })` to miss
cached entries that have a concrete value for the same property.

The new option is opt-in (default `false`) — no change to existing
behavior — so it is fully backward-compatible. Threaded through both
`QueryFilters` and `MutationFilters`.

Adds unit tests for `partialMatchKey` covering the broken case, the
nested-object case, and array preservation. Adds an end-to-end
`invalidateQueries` integration test demonstrating the fix at the
public API surface.

Refs TanStack#3741
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e1499c1-c1b1-4df8-9120-e5d6347852cd

📥 Commits

Reviewing files that changed from the base of the PR and between 5d0ee28 and 96d3a9e.

📒 Files selected for processing (1)
  • packages/query-core/src/index.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/query-core/src/index.ts

📝 Walkthrough

Walkthrough

Adds an opt-in ignoreUndefinedInKeys flag to QueryFilters/MutationFilters, forwards it through matchQuery/matchMutation, updates partialMatchKey to ignore undefined object properties during partial matches, and adds unit and integration tests.

Changes

Undefined property handling in query key matching

Layer / File(s) Summary
Type contracts and filter option definition
packages/query-core/src/utils.ts, packages/query-core/src/index.ts
QueryFilters and MutationFilters now include ignoreUndefinedInKeys?: boolean; new exported PartialMatchKeyOptions documents and is re-exported as a public type.
Integration in matchQuery/matchMutation
packages/query-core/src/utils.ts
matchQuery and matchMutation destructure ignoreUndefinedInKeys from filters and pass it to partialMatchKey for non-exact partial key matching.
Partial key matching implementation
packages/query-core/src/utils.ts
partialMatchKey overloads accept options?: PartialMatchKeyOptions; when enabled and both sides are plain objects, candidate properties with undefined are treated as missing prior to recursive comparison.
Unit and integration tests
packages/query-core/src/__tests__/utils.test.tsx, packages/query-core/src/__tests__/queryClient.test.tsx
Add tests for partialMatchKey with ignoreUndefinedInKeys (including nested objects and array behavior) and a regression test for invalidateQueries showing default vs. option-enabled matching.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

"I hop through keys both wide and thin,
Ignoring undefined with a joyful grin.
Tests now prove what used to hide,
Matching keys dance side by side.
🐇✨"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding an opt-in ignoreUndefinedInKeys filter option to query-core.
Description check ✅ Passed The PR description provides comprehensive context including summary, background, API usage, design notes, and test coverage that aligns with the description template's requirements.
Linked Issues check ✅ Passed The PR resolves the inconsistency between hashKey and partialMatchKey documented in #3741 and addressed in #4616 by implementing the opt-in ignoreUndefinedInKeys option with proper tests.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the ignoreUndefinedInKeys option: filter interface updates, matching logic modifications, type exports, and regression tests.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/query-core/src/utils.ts`:
- Around line 270-282: The new type PartialMatchKeyOptions is declared in utils
(symbol: PartialMatchKeyOptions) but not re-exported from the package public
entrypoint; update the module's public exports to include and export this type
(i.e., add PartialMatchKeyOptions to the existing re-export list alongside
MutationFilters, QueryFilters, SkipToken, and Updater) so downstream code can
import it from the package root.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8a47e77a-67e8-4f35-8f70-c897a5b9e792

📥 Commits

Reviewing files that changed from the base of the PR and between 93e7d39 and 3a25529.

📒 Files selected for processing (3)
  • packages/query-core/src/__tests__/queryClient.test.tsx
  • packages/query-core/src/__tests__/utils.test.tsx
  • packages/query-core/src/utils.ts

Comment thread packages/query-core/src/utils.ts
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.

1 participant