Skip to content

fix: encode X-Error header for server function errors with non-latin1 messages (#1874)#2215

Merged
birkskyum merged 2 commits into
mainfrom
fix-1874-unicode-error-header
Jul 18, 2026
Merged

fix: encode X-Error header for server function errors with non-latin1 messages (#1874)#2215
birkskyum merged 2 commits into
mainfrom
fix-1874-unicode-error-header

Conversation

@brenelz

@brenelz brenelz commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Problem

Closes #1874. When a server function throws an Error whose message contains characters above U+00FF (e.g. "Ошибка 🚀"), the request crashes instead of surfacing the error.

In packages/start/src/fns/handler.ts, the catch block assigns the raw error message directly to the X-Error response header. HTTP header values must be ByteString-safe (chars ≤ U+00FF), so Headers.set throws a TypeError inside the catch block. The result is a bare, unhandled 500 with no X-Error header and no serialized body — so the client (fns/client.ts) never sees X-Error, never throws the deserialized error, and the route section hangs empty instead of rendering the ErrorBoundary.

Fix

  • Add toHeaderValue(): strips newlines (as before), then encodeURIComponents the value only when it contains non-latin1 characters (ASCII messages stay human-readable), with a fallback to "true" on the lone-surrogate edge case. The client only checks response.headers.has("X-Error") — the value itself is unused — so the real error message continues to travel in the seroval-serialized body that the client throws.
  • Return the constructed headers (which carries X-Error) instead of the discarded body.headers in the body-error path, so X-Error propagates consistently with the seroval path. Previously this variable was built and then thrown away.

Testing

  • Added an e2e test (apps/tests): a route with a server function that throws a unicode-message error, and a test asserting the message reaches the client via the X-Error path. Verified it fails without the fix and passes with it; the full server-function e2e suite is green (20/20).
  • Manually verified against a prod build of a repro app: the /_server request now returns 200 with an encoded x-error header, the client navigates, and the ErrorBoundary renders caught: Ошибка 🚀 ünïcode — special chars.

🤖 Generated with Claude Code

… messages (#1874)

A server function throwing an Error whose message contains characters above
U+00FF (e.g. "Ошибка 🚀") crashed the request: the raw message was assigned to
the X-Error response header, and because header values must be ByteString-safe,
Headers.set threw a TypeError inside the catch block. That produced a bare 500
with no X-Error header and no serialized body, so the client never threw the
deserialized error and the route section hung empty instead of rendering the
ErrorBoundary.

Add toHeaderValue() to strip newlines and encodeURIComponent the value only when
it contains non-latin1 characters (ASCII messages stay readable), falling back to
"true" on the lone-surrogate edge case. Also return the constructed `headers`
(which carries X-Error) instead of the discarded `body.headers` in the body-error
path, so X-Error propagates consistently with the seroval path.

Add an e2e test exercising the server-fn error path with a unicode message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@netlify

netlify Bot commented Jul 18, 2026

Copy link
Copy Markdown

Deploy Preview for solid-start-landing-page ready!

Name Link
🔨 Latest commit 0d3c937
🔍 Latest deploy log https://app.netlify.com/projects/solid-start-landing-page/deploys/6a5c030a1403290007738f6b
😎 Deploy Preview https://deploy-preview-2215--solid-start-landing-page.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@changeset-bot

changeset-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 0d3c937

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

This PR includes changesets to release 1 package
Name Type
@solidjs/start 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

@pkg-pr-new

pkg-pr-new Bot commented Jul 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@solidjs/start@2215

commit: 0d3c937

@birkskyum
birkskyum merged commit 9d91484 into main Jul 18, 2026
10 checks passed
@birkskyum
birkskyum deleted the fix-1874-unicode-error-header branch July 18, 2026 22:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Client side hung after throwing Error message with unicode characters

2 participants