trpc / trpc/trpc

bug: Unstable streaming responses with httpBatchStreamLink on React Native / Expo

Open
#6,996 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

🐛 bug: unconfirmed
Dominant language
TypeScript
Stars
40.6k
Forks
1.7k
Avg merge
1d 22h
Merged PRs (30d)
22

Description

Provide environment information

OS: Linux 6.17.7 Arch Linux
CPU: (8) x64 Intel(R) Core(TM) Ultra 5 226V
Memory: 6.43 GB / 14.97 GB
Container: Yes
Shell: 5.9 - /usr/bin/zsh
Binaries:
Node: 24.11.0 - ~/.asdf/installs/nodejs/24.11.0/bin/node
pnpm: 10.17.0 - ~/.asdf/installs/nodejs/24.11.0/bin/pnpm
npmPackages:
typescript => 5.9.2
expo => 54.0.9
react-native => 0.81.4
@trpc/client => 11.7.1
@trpc/server => 11.7.1
@trpc/tanstack-react-query => 11.7.1
@tanstack/react-query => 5.90.1

Describe the bug

When using httpBatchStreamLink with tRPC in an Expo (React Native) app, the client occasionally fails to parse streamed responses.

Primary error:

Roughly 20% of the time in the reproduction app I've provided, when the app triggers a refetch (via the "Refresh" button), the following error occurs:

[TRPCClientError: JSON Parse error: Unexpected character: <Some character>]
In our app, once this happens, all subsequent batched queries fail with similar errors.

function createConsumerStream(from) {
	const stream = createLineAccumulator(from);
	let sentHead = false;
	return stream.pipeThrough(new TransformStream({ transform(line, controller) {
		if (!sentHead) {
			👉 const head = JSON.parse(line);
			controller.enqueue(head);
			sentHead = true;
		} else {
			const chunk = JSON.parse(line);
			controller.enqueue(chunk);
		}
	} }));
}
Secondary errors:

The issue also appears intermittently when the Expo app first starts, sometimes showing:
[TRPCClientError: Unknown error]

In some cases, another error indicates that the response is not an AsyncIterable.

The implementation follows the official tRPC documentation for React Native streaming:
👉 https://trpc.io/docs/client/links/httpBatchStreamLink#react-native

Link to reproduction

https://github.com/AkisArou/trpc-repro

To reproduce
pnpm dev:node   # Start the Node.js streaming server
pnpm dev:expo   # Start the Expo client

Then:

  1. Press the Refresh button in the app.
  2. About 1 in 5 times, a JSON parse error is thrown.
Additional information

Relevant Source Files:

  • tRPC router definition: packages/server/src/trpc.ts
  • tRPC client definition: packages/client/src/trpc.ts
  • Node.js server entry point: apps/node-app/src/index.ts
  • Expo app tRPC usage: apps/expo-app/app/_layout.tsx
👨‍👧‍👦 Contributing
  • 🙋‍♂️ Yes, I'd be down to file a PR fixing this bug!

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 reproduction commands pnpm dev:node and pnpm dev:expo, then inspect packages/client/src/trpc.ts around createConsumerStream and the referenced router, server entry point, and Expo layout files. Use the Refresh button to reproduce the intermittent parse failure and compare the streamed response handling with the documented React Native setup. Done means repeated refreshes no longer produce JSON parse, unknown-error, or non-AsyncIterable failures.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, react-native, typescript
Domain
api, mobile, stream-processing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.