Skip to content

fix: streamed Suspense boundary error leaks the raw message in prod #478

Description

@vivek7405

Problem

The page-level streaming path in packages/server/src/ssr.js (streamingHtmlResponse, ~line 1509) builds <p>error: ${escapeHtml(msg)}</p> for a rejected or throwing streamed Suspense boundary in both dev and prod, leaking the internal error message (a DB error, a stack-derived path) to the client.

This is inconsistent with the framework's own SSR error-isolation policy. render-server.js's defaultSSRErrorTemplate is prod-silent, and the core renderToStream Suspense boundary path (render-server.js ~line 1442-1444) already routes boundary errors through it. The two streaming implementations disagree.

Design / approach

Thread the dev flag into streamingHtmlResponse (the call site in ssrPage has opts.dev) and gate the message: dev surfaces error: <msg>, prod emits '' (a silent isolated boundary), matching defaultSSRErrorTemplate.

Found during the #470 fresh-context review. Pre-existing on main (not a #470 regression). Narrow to trigger: per-component async-render throws are already isolated (render-server.js lines 560-585), so this catch only fires on a top-level boundary-promise rejection or a non-isolated renderToString throw. Deferred to its own focused PR rather than expanding #470's scope.

Acceptance criteria

  • streamingHtmlResponse gates the streamed-boundary error message on dev (prod emits no message).
  • The two streaming error paths (ssr.js page streamer and render-server.js renderToStream) are consistent (both prod-silent).
  • Integration test: a throwing/rejecting-suspense fixture driven through createRequestHandler in prod vs dev, asserting the streamed body OMITS the message in prod and INCLUDES it in dev.
  • Docs / AGENTS.md updated if any public surface changed (likely N/A).

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions