TanStack / TanStack/query

[vue-query] queryClient.fetchQuery passes getter options through without unwrapping

Open
#11,102 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
50.3k
Forks
4.2k
Avg merge
18h 25m
Merged PRs (30d)
200

Description

Describe the bug

QueryClient.fetchQuery in @tanstack/vue-query has an overload that accepts getter-function options, but the runtime implementation currently passes that top-level function through to query-core instead of evaluating it first.

The overload allows this shape:

queryClient.fetchQuery(() => ({
  queryKey: ["foo", ref("bar")],
  queryFn,
}))

But the implementation calls cloneDeepUnref(options) directly. cloneDeepUnref unwraps refs and nested query-key getters, but it does not call a top-level function value. As a result, query-core receives the function itself instead of the resolved FetchQueryOptions object.

Your minimal, reproducible example

Focused regression test in the linked PR: https://github.com/TanStack/query/pull/11103/files#diff-3d6cc18a7ff7e8e5afb08c0e3cba8d9f3e08fb9c6f6c59f1f5f58dc12f3f8b8e

Minimal code shape:

import { QueryClient } from "@tanstack/vue-query"
import { ref } from "vue"

const queryClient = new QueryClient()
const queryFn = () => Promise.resolve("mock")

queryClient.fetchQuery(() => ({
  queryKey: ["foo", ref("bar")],
  queryFn,
}))
Steps to reproduce
  1. Create a Vue Query QueryClient.
  2. Call queryClient.fetchQuery with a getter function returning FetchQueryOptions.
  3. Observe that the getter is not evaluated before delegating to query-core.

A focused test shows the current behavior clearly:

queryClient.fetchQuery(() => ({
  queryKey: queryKeyRef,
  queryFn: fn,
}))

expect(QueryClientOrigin.prototype.fetchQuery).toHaveBeenCalledWith({
  queryKey: queryKeyUnref,
  queryFn: fn,
})

Currently the received argument is [Function anonymous].

Expected behavior

queryClient.fetchQuery(() => options) should evaluate the top-level getter, then deep-unref the returned options object before passing it to query-core.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform
  • OS: macOS
  • Browser: N/A
  • Runtime: Node.js v24.13.0
  • Adapter: vue-query
  • Vue runtimes tested: Vue 2 / Vue 2.7 / Vue 3
Tanstack Query adapter

vue-query

TanStack Query version

v5.101.4 / current main branch at commit 86bb8a6fb

TypeScript version

TypeScript 5.9.3 in the local repo; package type tests also passed across the repo's configured TS 5.4 through TS 6.0 matrix.

Additional context

I could not find an existing open issue or PR for this with these searches:

  • vue queryClient fetchQuery getter options cloneDeepUnref
  • fetchQuery getter function options vue-query

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the @tanstack/vue-query QueryClient.fetchQuery implementation and its call to cloneDeepUnref. Review the focused regression test linked in PR #11103, then verify that a getter-returned options object is evaluated and unwrapped before reaching query-core.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.