Skip to content

Conversation

@ahmethos
Copy link
Contributor

@ahmethos ahmethos commented Nov 15, 2025

Add failing test for empty streams and update implementation to avoid returning undefined. Includes changeset for patch release.

🎯 Changes

  • Added a new test case (should handle empty streams) that reproduces the issue where streamedQuery throws when the underlying AsyncIterable yields no values.
  • Updated streamedQuery implementation to fall back to initialValue when getQueryData returns undefined.
  • This prevents React Query from entering an error state for valid empty streams and aligns behavior with expected semantics.
  • Included a patch-level changeset for @tanstack/query-core.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes

    • Fixed streamedQuery to avoid returning undefined for empty streams — now consistently falls back to the initial value.
  • Tests

    • Added test coverage for empty-stream scenarios to verify correct lifecycle and result handling.
  • Documentation

    • Clarified docs to state the initial value is returned when a stream yields no values.
  • Chores

    • Added a changeset documenting a patch update and the fix.

…alues

Add failing test for empty streams and update implementation to avoid returning undefined.
Includes changeset for patch release.
@changeset-bot
Copy link

changeset-bot bot commented Nov 15, 2025

🦋 Changeset detected

Latest commit: 9ac9722

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@tanstack/query-core Patch
@tanstack/angular-query-experimental Patch
@tanstack/query-async-storage-persister Patch
@tanstack/query-broadcast-client-experimental Patch
@tanstack/query-persist-client-core Patch
@tanstack/query-sync-storage-persister Patch
@tanstack/react-query Patch
@tanstack/solid-query Patch
@tanstack/svelte-query Patch
@tanstack/vue-query Patch
@tanstack/angular-query-persist-client Patch
@tanstack/react-query-persist-client Patch
@tanstack/solid-query-persist-client Patch
@tanstack/svelte-query-persist-client Patch
@tanstack/react-query-devtools Patch
@tanstack/react-query-next-experimental Patch
@tanstack/solid-query-devtools Patch
@tanstack/svelte-query-devtools Patch
@tanstack/vue-query-devtools Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 15, 2025

Walkthrough

A patch-level fix ensures streamedQuery returns the provided initialValue instead of undefined when the async stream yields no items. The change replaces a non-null assertion with a nullish-coalescing fallback, updates JSDoc/docs, and adds a test covering empty-stream behavior.

Changes

Cohort / File(s) Summary
Changeset documentation
.changeset/puny-walls-eat.md
Adds a changeset documenting a patch release for @tanstack/query-core describing the streamedQuery fix for empty streams.
Test coverage
packages/query-core/src/__tests__/streamedQuery.test.tsx
Adds "should handle empty streams" test that supplies an empty async generator and asserts initial pending state then success with an empty data array.
Core implementation
packages/query-core/src/streamedQuery.ts
Replaces a non-null assertion with nullish coalescing to return initialValue when cached query data is undefined; updates JSDoc to document this behavior.
Documentation
docs/reference/streamedQuery.md
Updates initialValue description to state it is returned when the stream yields no values, aligning docs with behavior change.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant C as Caller
    participant SQ as streamedQuery
    participant S as Stream (async generator)

    alt Stream yields chunks
        C->>SQ: invoke streamFn
        SQ->>S: start stream
        S-->>SQ: chunk1
        SQ-->>C: emit chunk1
        S-->>SQ: chunkN
        SQ-->>C: emit chunkN
        SQ-->>C: complete
    else Stream yields no chunks
        C->>SQ: invoke streamFn
        SQ->>S: start stream
        S-->>SQ: (no items)
        SQ-->>C: return initialValue (fallback)
        SQ-->>C: complete
    end

    Note over SQ: Return now uses nullish coalescing to fall back to initialValue
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Single-line logic change in streamedQuery.ts plus JSDoc update.
  • New test adds coverage but follows existing patterns.
  • Review attention:
    • packages/query-core/src/streamedQuery.ts — confirm nullish-coalesce semantics and potential edge cases.
    • packages/query-core/src/__tests__/streamedQuery.test.tsx — timing/assertion robustness.
    • docs/reference/streamedQuery.md — ensure wording matches behavior.

Suggested reviewers

  • TkDodo

Poem

🐰
A stream so quiet, no droplets fall,
I waited in burrows through tunnels small.
With a gentle coalesce, hope's not denied—
The initial carrot stays by my side. 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: falling back to initialValue when streams yield no values, directly matching the core implementation change.
Description check ✅ Passed The description follows the template structure with all required sections completed: detailed Changes section, completed Checklist with both items checked, and Release Impact section with changeset confirmed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 709fad2 and 1e269ac.

📒 Files selected for processing (1)
  • docs/reference/streamedQuery.md (1 hunks)
🔇 Additional comments (1)
docs/reference/streamedQuery.md (1)

43-43: Documentation accurately reflects the empty-stream handling fix.

The updated wording on the initialValue parameter now correctly documents the new fallback behavior when the stream yields no values, aligning with the implementation changes that use nullish coalescing to prevent returning undefined.

Tip

📝 Customizable high-level summaries are now available!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide custom instructions to shape the summary (bullet lists, tables, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example:

"Create a concise high-level summary as a bullet-point list. Then include a Markdown table showing lines added and removed by each contributing author."


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
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: 0

🧹 Nitpick comments (2)
packages/query-core/src/streamedQuery.ts (1)

44-44: Update documentation to reflect new behavior.

The JSDoc for initialValue should mention that it's also returned when the stream yields no values, not just "while the first chunk is being fetched."

Apply this diff to clarify the documentation:

- * @param initialValue - Initial value to be used while the first chunk is being fetched.
+ * @param initialValue - Initial value to be used while the first chunk is being fetched, and returned if the stream yields no values.
packages/query-core/src/__tests__/streamedQuery.test.tsx (1)

131-160: LGTM! Test correctly validates empty stream handling.

The test properly covers the scenario where an AsyncIterable yields no values, ensuring streamedQuery returns the initialValue (empty array) instead of undefined.

Optional: Consider simplifying the empty stream syntax.

The empty async iterator on line 138 could be more concise:

-    const observer = new QueryObserver(queryClient, {
-      queryKey: key,
-      queryFn: streamedQuery({
-        streamFn: () => { return {async *[Symbol.asyncIterator]() {}}},
-      }),
-    })
+    const observer = new QueryObserver(queryClient, {
+      queryKey: key,
+      queryFn: streamedQuery({
+        streamFn: async function* () {},
+      }),
+    })

Also consider removing the blank lines at 132 and 159 for consistency with other tests in the file.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6226325 and 2749ece.

📒 Files selected for processing (3)
  • .changeset/puny-walls-eat.md (1 hunks)
  • packages/query-core/src/__tests__/streamedQuery.test.tsx (1 hunks)
  • packages/query-core/src/streamedQuery.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-02T17:57:33.184Z
Learnt from: TkDodo
Repo: TanStack/query PR: 9612
File: packages/query-async-storage-persister/src/asyncThrottle.ts:0-0
Timestamp: 2025-09-02T17:57:33.184Z
Learning: When importing from tanstack/query-core in other TanStack Query packages like query-async-storage-persister, a workspace dependency "tanstack/query-core": "workspace:*" needs to be added to the package.json.

Applied to files:

  • .changeset/puny-walls-eat.md
📚 Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • .changeset/puny-walls-eat.md
  • packages/query-core/src/streamedQuery.ts
🧬 Code graph analysis (1)
packages/query-core/src/__tests__/streamedQuery.test.tsx (1)
packages/query-core/src/streamedQuery.ts (1)
  • streamedQuery (46-99)
🔇 Additional comments (2)
packages/query-core/src/streamedQuery.ts (1)

97-97: LGTM! Correct fix for empty streams.

The nullish coalescing operator properly handles the case where getQueryData returns undefined (when the stream yields no values and nothing was written to cache), falling back to initialValue as expected.

.changeset/puny-walls-eat.md (1)

1-5: LGTM! Changeset is well-documented.

The patch-level bump is appropriate for this bug fix, and the description clearly explains the change.

Copy link
Collaborator

@TkDodo TkDodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also update the docs:

- `initialValue?: TData = TQueryFnData`
- Optional
- Defines the initial data to be used while the first chunk is being fetched.
- It is mandatory when custom `reducer` is provided.
- Defaults to an empty array.

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Nov 16, 2025
@nx-cloud
Copy link

nx-cloud bot commented Nov 16, 2025

View your CI Pipeline Execution ↗ for commit 9ac9722

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 4m 55s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 20s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-16 18:24:47 UTC

@TkDodo TkDodo merged commit eb559a6 into TanStack:main Nov 16, 2025
6 checks passed
@codecov
Copy link

codecov bot commented Nov 16, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.81%. Comparing base (6226325) to head (9ac9722).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #9876       +/-   ##
===========================================
+ Coverage   45.78%   59.81%   +14.03%     
===========================================
  Files         200      129       -71     
  Lines        8413     5627     -2786     
  Branches     1923     1539      -384     
===========================================
- Hits         3852     3366      -486     
+ Misses       4113     1956     -2157     
+ Partials      448      305      -143     
Components Coverage Δ
@tanstack/angular-query-experimental 93.85% <ø> (ø)
@tanstack/eslint-plugin-query ∅ <ø> (∅)
@tanstack/query-async-storage-persister 43.85% <ø> (ø)
@tanstack/query-broadcast-client-experimental 24.39% <ø> (ø)
@tanstack/query-codemods ∅ <ø> (∅)
@tanstack/query-core 97.38% <100.00%> (ø)
@tanstack/query-devtools 3.48% <ø> (ø)
@tanstack/query-persist-client-core 80.00% <ø> (ø)
@tanstack/query-sync-storage-persister 84.61% <ø> (ø)
@tanstack/query-test-utils ∅ <ø> (∅)
@tanstack/react-query 96.01% <ø> (ø)
@tanstack/react-query-devtools 10.00% <ø> (ø)
@tanstack/react-query-next-experimental ∅ <ø> (∅)
@tanstack/react-query-persist-client 100.00% <ø> (ø)
@tanstack/solid-query 77.81% <ø> (ø)
@tanstack/solid-query-devtools 61.90% <ø> (ø)
@tanstack/solid-query-persist-client 100.00% <ø> (ø)
@tanstack/svelte-query ∅ <ø> (∅)
@tanstack/svelte-query-devtools ∅ <ø> (∅)
@tanstack/svelte-query-persist-client ∅ <ø> (∅)
@tanstack/vue-query 71.28% <ø> (ø)
@tanstack/vue-query-devtools ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot mentioned this pull request Nov 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: query-core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants