Skip to content

fix(query): apply queryOptions mutator to generated invalidate function (#3190) - #3290

Merged
melloware merged 3 commits into
orval-labs:masterfrom
zeriong:fix/use-invalidate-respect-query-options-mutator-3190
Apr 29, 2026
Merged

fix(query): apply queryOptions mutator to generated invalidate function (#3190)#3290
melloware merged 3 commits into
orval-labs:masterfrom
zeriong:fix/use-invalidate-respect-query-options-mutator-3190

Conversation

@zeriong

@zeriong zeriong commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #3190.

When query.queryOptions is configured with a mutator that augments
the queryKey (for example, prepending a tenant prefix), generated
invalidateXxx helpers ignored the mutator and called
queryClient.invalidateQueries with the raw queryKey from
getXxxQueryKey(). As a result, the keys never matched the keys
that the query hook actually wrote into the cache, and invalidation
silently no-op'd.

This change routes the queryKey passed to invalidateQueries
through the queryOptions mutator when one is configured and is not a
hook. The hook case is intentionally skipped because the generated
invalidateXxx helpers are plain async functions and cannot legally
invoke React/Vue hooks.

What changed

  • packages/query/src/query-generator.ts: derive a single
    invalidateQueryKeyExpr that respects both query.queryKey
    (queryKeyMutator) and query.queryOptions (queryOptionsMutator,
    non-hook only) and use it in the emitted invalidateXxx body.
  • tests/mutators/custom-query-options.ts: new fixture that mirrors
    the mutator pattern from the issue
    ({ ...args, queryKey: [tenant, ...args.queryKey] }).
  • tests/configs/react-query.config.ts: new
    useInvalidateWithQueryOptionsMutator case wiring the fixture
    through the existing petstore spec.
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/:
    generated baseline so future regressions are caught.

Behavior before vs after

Before:

await queryClient.invalidateQueries(
  { queryKey: getListPetsQueryKey(params) },
  options,
);

After (with a queryOptions mutator like
(opts) => ({ ...opts, queryKey: ['tenant-abc', ...opts.queryKey] })):

await queryClient.invalidateQueries(
  {
    queryKey: customQueryOptions({
      queryKey: getListPetsQueryKey(params),
    }).queryKey,
  },
  options,
);

The shape looks busy, but it's the only way to trust the mutator —
invoke it once and use its .queryKey.
If you see a better approach, please leave a comment with a small
example snippet.

The no-mutator output is byte-identical to before (verified against
the existing use-invalidate snapshot), so consumers without a
queryOptions mutator are unaffected.

Test plan

  • bun vitest run (2303 passed; the 3 unrelated
    resolve-version failures also fail on master with no changes,
    see notes below).
  • bun run test:snapshots (3739 passed; 21 new snapshots
    written for the new case).
  • bun run lint (24 successful).
  • bun run typecheck (12 successful, full recompile after
    cache miss).
  • bun run build (12 successful).
  • Manual diff of tests/generated/react-query/use-invalidate vs
    tests/generated/react-query/use-invalidate-with-query-options-mutator
    to confirm only the new case routes through the mutator.

Notes for reviewers

  • The 3 vitest failures in
    @orval/core/src/utils/resolve-version.test.ts reproduce on a
    clean master checkout in this environment; they depend on locally
    installed @faker-js/faker and remeda packages and are not
    touched by this PR.
  • A similar pattern exists in setQueryDataKeyExpr /
    getQueryDataKeyExpr (they only honor queryKeyMutator, not
    queryOptionsMutator). That is left as a deliberate follow-up
    to keep this PR scoped to the bug reported in useInvalidate does not contain mutator query keys #3190.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for custom query options mutators in React Query integration, enabling enhanced control over query key generation and invalidation behavior.
  • Refactor

    • Centralized query key construction logic to improve consistency between invalidation and set-query-data operations.
  • Tests

    • Added comprehensive test coverage for custom query options mutator functionality.

zeriong added 3 commits April 29, 2026 18:25
…val-labs#3190)

Generated invalidateXxx helpers used the raw queryKey function and
therefore ignored any keys appended by the user-supplied
query.queryOptions mutator (e.g. tenant prefixes), making invalidation
miss the cache entries that were actually written.

Route the invalidate queryKey through the mutator when one is
configured and is not a hook, so the final key matches what the query
hook writes. Hook-shaped mutators are skipped because the invalidate
helper is a plain async function and cannot call hooks.
…-labs#3190)

Add a react-query test config that combines useInvalidate with a
queryOptions mutator that prepends a tenant key, plus the mutator
fixture itself. The fixture mirrors the minimal repro from the issue
so the generated output is exercised end-to-end by the snapshot
suite.
…val-labs#3190)

Capture the generated client for the new test config so future
regressions in the invalidate-key resolution path are caught by the
snapshot suite.
@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bad89702-5aa5-497f-9faa-18e319a738f7

📥 Commits

Reviewing files that changed from the base of the PR and between aab9224 and 75b3024.

📒 Files selected for processing (24)
  • packages/query/src/query-generator.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/endpoints.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/cat.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/catType.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/createPetsBody.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/createPetsParams.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/createPetsSort.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/dachshund.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/dachshundBreed.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/dog.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/dogType.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/error.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/index.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/labradoodle.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/labradoodleBreed.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/listPetsParams.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/listPetsSort.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/pet.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/petCallingCode.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/petCountry.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/petWithTag.ts
  • tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/pets.ts
  • tests/configs/react-query.config.ts
  • tests/mutators/custom-query-options.ts

📝 Walkthrough

Walkthrough

The PR refactors query-key generation in the code generator to centralize base key construction and apply query-option mutations during invalidation, ensuring invalidateQueries uses the final mutated key expression instead of the pre-mutation base function.

Changes

Cohort / File(s) Summary
Query Generator Core
packages/query/src/query-generator.ts
Refactors invalidation and set-query-data key generation to compute base query keys via queryKeyMutator then route through queryOptionsMutator for invalidation, ensuring invalidate helpers use the post-mutated key expression (invalidateQueryKeyExpr) rather than the pre-mutator key function.
React Query Test Snapshots
tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/endpoints.ts, tests/__snapshots__/react-query/use-invalidate-with-query-options-mutator/model/*
Generated snapshot files demonstrating React Query hooks, query-option builders, invalidation helpers, and model definitions for Petstore API endpoints with custom query-options mutator integration.
Test Configuration & Helpers
tests/configs/react-query.config.ts, tests/mutators/custom-query-options.ts
Adds new Orval config for useInvalidateWithQueryOptionsMutator test case with override.query.useInvalidate and override.query.queryOptions mutator settings; introduces customQueryOptions helper that prepends tenant prefix to query keys.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #3173 — Modifies query-key construction logic in the same generator file for related query-expression handling.
  • #3136 — Refactors set-query-data and invalidate helpers' query-key construction in query-generator.ts.
  • #3237 — Related to invalidation code generation and how invalidateQueries keys/parameters are emitted.

Suggested labels

tanstack-query, bug

Suggested reviewers

  • melloware

Poem

🐰 A query key, once broken in the night,
Now mutates correctly—hooray, all is right!
With options applied and keys all in place,
Invalidation rejoices, a smile on its face! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(query): apply queryOptions mutator to generated invalidate function (#3190)' clearly and specifically describes the main change: applying the queryOptions mutator to invalidate functions, directly addressing issue #3190.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #3190 by modifying query-generator.ts to derive invalidateQueryKeyExpr that respects both query.queryKey and the queryOptions mutator, with supporting test fixtures and snapshots validating the fix.
Out of Scope Changes check ✅ Passed All changes directly support the core objective: query-generator.ts refactors invalidation key generation, tests/mutators/custom-query-options.ts provides the test fixture, tests/configs/react-query.config.ts configures the test scenario, and snapshot files capture generated output.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ 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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@melloware melloware added the tanstack-query TanStack Query related issue label Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tanstack-query TanStack Query related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useInvalidate does not contain mutator query keys

2 participants