Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

[query-broadcast-client-experimental] broadcastQueryClient: an `added` event overwrites a receiving query that has no data (e.g. in error) with the sender's empty state

Offen
#12,213 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@lazerg arbeitet bereits daran.

Seit 20.10.2026.

  • #12215 von @lazerg — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
25/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Veraltet
Tech-Stack
react, typescript

Rechercherichtung

Read src/index.ts around lines 155–162 and 193–198 in the broadcast client package, then inspect the related change in #11391. The open pull request #12215 is already linked to this issue. Done means an added event no longer replaces a receiver’s settled error state with an empty pending state; the issue includes a minimal reproduction to check that behavior.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

Package: @tanstack/query-broadcast-client-experimental 5.104.3 (with @tanstack/query-core 5.104.3)

Describe the bug

When another tab creates a query, the receiving tab applies the sender's state on added whenever its own query has no data. A query that has no data but did settle (a failed query: status: 'error', errorUpdatedAt > 0) is replaced with the sender's brand-new state: status: 'pending', fetchStatus: 'idle', error: null, dataUpdatedAt: 0, errorUpdatedAt: 0.

The receiving query now looks like it is loading, but no fetch runs. Observers render a pending/loading UI indefinitely (until a refetch interval, focus or invalidation happens to trigger), and the error is lost.

src/index.ts, lines 193-198:

      } else if (type === 'added') {
        if (query) {
          if (query.state.data === undefined) {
            query.setState(state)
          }
          return
        }

The sender posts added straight from queryCache.build, before its fetch starts (lines 155-162), so the state it carries is the initial empty state:

    if (queryEvent.type === 'added') {
      safePost({
        type: 'added',
        queryHash,
        queryKey,
        state,
      })
    }

Minimal reproduction

  1. Tab A and tab B both call broadcastQueryClient({ queryClient }).
  2. In tab A, useQuery({ queryKey: ['x'], queryFn: () => Promise.reject(new Error('down')), retry: false }). It settles in status: 'error', with no data.
  3. Tab B creates the same query: either mount the same useQuery, or queryClient.getQueryCache().build(queryClient, { queryKey: ['x'] }) (for example, as a side effect of a prefetch that has not started yet).
  4. In tab A, the query is now status: 'pending', fetchStatus: 'idle', error: null, errorUpdatedAt: 0. The observer shows loading, and no request is in flight.

Without the plugin, the same can be shown in a single client:

const query = queryClient.getQueryCache().find({ queryKey: ['x'] })! // in error, no data
query.setState({ status: 'pending', fetchStatus: 'idle', data: undefined, dataUpdatedAt: 0, error: null, errorUpdatedAt: 0 })
// observers now report pending with no fetch running

Expected behavior

An added event carries nothing the receiver lacks when the sender's query has never settled. The receiver should keep its own state, in particular an error.

Suggested fix

Skip an incoming added state that never received data or an error:

      } else if (type === 'added') {
        if (query) {
          const incoming = state as QueryState
          if (
            query.state.data === undefined &&
            (incoming.dataUpdatedAt > 0 || incoming.errorUpdatedAt > 0)
          ) {
            query.setState(incoming)
          }
          return
        }

A stricter variant would apply added only when it is newer than the receiver's last outcome (max(dataUpdatedAt, errorUpdatedAt)).

Workaround we use

Our query projection detects an observed query left pending with fetchStatus: 'idle' and refetches it once through its observer.

Related

Follow-up to #11391, which made added skip a receiver that already has data. A receiver without data but with an error is still overwritten.

Vorherrschende Sprache
TypeScript
Sterne
50.4k
Forks
4.3k
Ø Merge
9 Std. 42 Min.
Gemergte PRs (30 T.)
590

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus TanStack/query

Alle Issues in TanStack/query

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.