remix-run/react-router · error · Error
Unable to decode turbo-stream response
Error message
Unable to decode turbo-stream response
What it means
With the single-fetch data strategy, loader/action results come back from a `.data` request encoded as a turbo-stream. The client runs `decodeViaTurboStream` on the response body inside a try/catch; any decoding failure (body not turbo-stream bytes, corrupted stream) hits the catch, which deliberately throws this generic error because the body has already been consumed and cannot be re-read or echoed. This means the response you received was not a valid turbo-stream payload.
Source
Thrown at packages/react-router/lib/dom/ssr/single-fetch.tsx:664
} else {
let typed = decoded.value as SingleFetchResult;
let routeId = targetRoutes?.[0];
invariant(routeId, "No routeId found for single fetch call decoding");
if ("redirect" in typed) {
data = { redirect: typed };
} else {
data = { routes: { [routeId]: typed } };
}
}
return { status: res.status, data };
} catch {
// Can't clone after consuming the body via turbo-stream so we can't
// include the body here. In an ideal world we'd look for a turbo-stream
// content type here, or even X-Remix-Response but then folks can't
// statically deploy their prerendered .data files to a CDN unless they can
// tell that CDN to add special headers to those certain files - which is a
// bit restrictive.
throw new Error("Unable to decode turbo-stream response");
}
}
// Note: If you change this function please change the corresponding
// encodeViaTurboStream function in server-runtime
export function decodeViaTurboStream(
body: ReadableStream<Uint8Array>,
global: Window | typeof globalThis,
) {
return decode(body, {
plugins: [
(type: string, ...rest: unknown[]) => {
// Decode Errors back into Error instances using the right type and with
// the right (potentially undefined) stacktrace
if (type === "SanitizedError") {
let [name, message, stack] = rest as [
string,
string,View on GitHub (pinned to 6beaca3952)
Solutions
- Open the network tab and inspect the failing `.data` request — the response body is almost certainly an HTML error/login page or empty; fix whatever serves it (auth redirect, 404 handler, gateway rule) to let the router's own response through.
- Exclude `.data` requests (by path suffix or `X-Remix-`/React Router data headers) from interceptors, service workers, and compression layers.
- If it happens right after a deploy, hard-refresh or clear the cache so client and server encodings match.
- For prerendered static hosting, verify the deployed `.data` files are byte-identical to the build output and served uncompressed-as-built.
Defensive patterns
Strategy: retry
Try / catch
// in a route error boundary
export function ErrorBoundary() {
const error = useRouteError();
if (error instanceof Error && /turbo-stream/.test(error.message)) {
return <button onClick={() => window.location.reload()}>Session out of date — reload</button>;
}
throw error;
} Prevention
- Bypass proxies/service workers for .data requests (match on the .data suffix).
- Serve prerendered .data files with the exact bytes and content type produced by the build.
- After deploys, prompt users to reload so client and server encodings match.
When it happens
Trigger: A proxy, auth gateway, or service worker intercepting the `.data` request and returning an HTML login/404 page instead of the turbo-stream body; a CDN serving a stale or wrong-content-type prerendered `.data` file; double compression (gzip/brotli applied twice) mangling the stream; severe client/server version skew after a deploy where old client code decodes a new server encoding.
Common situations: Corporate proxies or API gateways rewriting responses for non-HTML content types; hosting static prerendered `.data` files with wrong MIME/compression settings; a middleware returning `json()` for `.data` requests; deploys where the browser holds an old HTML bundle that requests `.data` from a new server.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unable to decode RSC response
- There was a problem fetching the file from GitHub. The reque
- There was a problem fetching the file from GitHub. No asset
- There was a problem fetching the file${isGithubUrl ? " from
- There was a problem fetching the file${isGithubUrl ? " from
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/705d2de445648b52.
Report an issue: GitHub.