Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

[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

Ouverte
#12,213 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@lazerg y travaille déjà.

Depuis le 20/10/2026.

  • #12215 par @lazerg — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
25/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
À l'abandon
Stack technique
react, typescript

Piste de recherche

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.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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.

Langage dominant
TypeScript
Étoiles
50.4k
Forks
4.3k
Merge moyen
9 h 42 min
PR mergées (30 j)
590

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de TanStack/query

Toutes les issues de TanStack/query

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.