facebook/react · error · Error
React currently only supports piping to one writable stream.
Error message
React currently only supports piping to one writable stream.
What it means
renderToPipeableStream (react-server-dom-webpack/server.node) returns a {pipe, abort} object whose output may flow to exactly one writable destination. The first pipe() call sets hasStartedFlowing; any second call throws, because the Fizz server cannot fan a single render out to multiple writables.
Source
Thrown at packages/react-server-dom-webpack/src/server/ReactFlightDOMServerNode.js:211
options ? options.identifierPrefix : undefined,
options ? options.temporaryReferences : undefined,
options ? options.startTime : undefined,
__DEV__ && options ? options.environmentName : undefined,
__DEV__ && options ? options.filterStackFrame : undefined,
debugChannelReadable !== undefined,
);
let hasStartedFlowing = false;
startWork(request);
if (debugChannelWritable !== undefined) {
startFlowingDebug(request, debugChannelWritable);
}
if (debugChannelReadable !== undefined) {
startReadingFromDebugChannelReadable(request, debugChannelReadable);
}
return {
pipe<T: Writable>(destination: T): T {
if (hasStartedFlowing) {
throw new Error(
'React currently only supports piping to one writable stream.',
);
}
hasStartedFlowing = true;
startFlowing(request, destination);
destination.on('drain', createDrainHandler(destination, request));
destination.on(
'error',
createCancelHandler(
request,
'The destination stream errored while writing data.',
),
);
// We don't close until the debug channel closes.
if (!__DEV__ || debugChannelReadable === undefined) {
destination.on(
'close',
createCancelHandler(request, 'The destination stream closed early.'),View on GitHub (pinned to eafeac097b)
Solutions
- Call renderToPipeableStream once per request and pipe exactly once; enforce with a `let piped = false` guard if control flow is complex
- If the output is needed in two places, pass a PassThrough to pipe() and branch from it — never call pipe() again
- On destination failure use abort()/onError and start a fresh renderToPipeableStream instead of re-piping
Example fix
// before
const {pipe} = renderToPipeableStream(<App />, opts);
router.get('/a', (req, res) => pipe(res));
router.get('/b', (req, res) => pipe(res)); // second pipe -> throws
// after: one render and one pipe per request
router.get('/:page', (req, res) => {
const {pipe} = renderToPipeableStream(<App />, opts);
pipe(res);
}); Defensive patterns
Strategy: validation
Validate before calling
function pipeOnce(pipe, destination) {
if (pipeOnce.called) {
throw new Error('This stream was already piped — create a new renderToPipeableStream instead.');
}
pipeOnce.called = true;
pipe(destination);
} Prevention
- Create one renderToPipeableStream per request and pipe exactly once
- If you need the output in two sinks, pass a PassThrough to pipe() and branch from it
- On destination errors use abort() and start a fresh render — never re-pipe
When it happens
Trigger: Calling stream.pipe(destination) twice — for example a success path and an error/fallback path that both pipe, retry logic that re-pipes after a destination error, or one renderToPipeableStream result shared across two request handlers or sockets.
Common situations: Custom Express/Fastify SSR servers caching the render result between requests; error handlers that attempt to pipe a fallback shell after piping already began; middleware trying to tee output into a cache and the response by calling pipe twice.
Related errors
- 417
- React currently only supports piping to one writable stream.
- React currently only supports piping to one writable stream.
- Server Functions cannot be called during initial render. Thi
- React currently only supports piping to one writable stream.
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/801d34817e6b12f7.
Report an issue: GitHub.