Skip to content

fix: SSR invariant dehydration errors with bun #4228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Cyenoch
Copy link

@Cyenoch Cyenoch commented May 22, 2025

Related: #3989

The script assigned to __TSR_SSR__.dehydrated appears outside the </html> tag. When the entry script /_build/assets/client-BJoNZ2zg.js is cached locally by the browser, even if the entry script is async, the script outside the html may still be executed after the entry script.

const text = decodeChunk(chunk.value)

Problems occur when text is complete HTML

const bodyEndMatch = chunkString.match(patternBodyEnd)
const htmlEndMatch = chunkString.match(patternHtmlEnd)

const remaining = chunkString.slice(index + headTag.length)

bodyEndMatch is assigned before the !headStarted branch processes chunkString.

chunkString.slice(0, bodyEndIndex) + getBufferedRouterStream(),

The length of bodyEndIndex obtained here will exceed the length of the modified chunkString, resulting in <script> being appended after </html>

Image

The solution is make sure hydrate is executed after TSR_SSR.dehydrated is assigned a value by other means.

Copy link

nx-cloud bot commented May 22, 2025

View your CI Pipeline Execution ↗ for commit 846bf44.

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 1m 37s View ↗

☁️ Nx Cloud last updated this comment at 2025-05-25 09:36:29 UTC

Copy link

pkg-pr-new bot commented May 22, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@4228

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@4228

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@4228

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@4228

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@4228

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@4228

@tanstack/react-router-with-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-with-query@4228

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@4228

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@4228

@tanstack/react-start-config

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-config@4228

@tanstack/react-start-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-plugin@4228

@tanstack/react-start-router-manifest

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-router-manifest@4228

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@4228

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@4228

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@4228

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@4228

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@4228

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@4228

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@4228

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@4228

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@4228

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@4228

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@4228

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@4228

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@4228

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@4228

@tanstack/solid-start-config

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-config@4228

@tanstack/solid-start-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-plugin@4228

@tanstack/solid-start-router-manifest

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-router-manifest@4228

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@4228

@tanstack/start

npm i https://pkg.pr.new/TanStack/router/@tanstack/start@4228

@tanstack/start-api-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-api-routes@4228

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@4228

@tanstack/start-config

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-config@4228

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@4228

@tanstack/start-server-functions-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-client@4228

@tanstack/start-server-functions-fetcher

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-fetcher@4228

@tanstack/start-server-functions-handler

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-handler@4228

@tanstack/start-server-functions-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-server@4228

@tanstack/start-server-functions-ssr

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-ssr@4228

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@4228

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@4228

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@4228

commit: 846bf44

@Cyenoch
Copy link
Author

Cyenoch commented May 23, 2025

I think it would be better if ensure that all tsr-once is before the entry script

@schiller-manuel
Copy link
Contributor

I think it would be better if ensure that all tsr-once is before the entry script

that's not possible as values might stream in later

@schiller-manuel
Copy link
Contributor

how can I reproduce the issue locally?

@Cyenoch
Copy link
Author

Cyenoch commented May 26, 2025

how can I reproduce the issue locally?

For example:

cd example/react/start-material-ui

Update app.config.ts set server.preset = 'bun'

pnpm build

bun run .output/server/index.mjs

Open "localhost:3000" and enter F12 to switch the throttling to 3G

Tap reload button on browser navigation bar, after reloading for about a dozen times (client entry scripts cached in memory), Invariant failed started to appear.

image

image

image

@Cyenoch
Copy link
Author

Cyenoch commented May 26, 2025

image

Even if tsr-once is in html, Invariant failed will still appear. So I think if this script is before client entry script, the problem should be solved. Or the other way to make sure hydrate is executed after __TSR_SSR__.dehydrated is assigned a value by other means.

@Cyenoch
Copy link
Author

Cyenoch commented May 26, 2025

Change script loading attribute from async to defer seems to solve this problem

@schiller-manuel
Copy link
Contributor

i found the issue, a synchronization error when injecting the scripts. I'll fix this as part of a rewrite of this section.

@Cyenoch
Copy link
Author

Cyenoch commented May 27, 2025

very thankful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants