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 in this package returns a handle with pipe() and abort(). React's Flight server writes each request to exactly one Writable; a hasStartedFlowing flag makes a second pipe() on the same handle throw instead of interleaving two output streams and corrupting the payload.
Source
Thrown at packages/react-server-dom-esm/src/server/ReactFlightDOMServerNode.js:204
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
- Render once per destination: call renderToPipeableStream again for each additional Writable
- Tee manually by forwarding the first destination's chunk events to the second sink
- Wrap pipe in a once-guard so a second call is rejected with your own clear error
Example fix
// before
const {pipe} = renderToPipeableStream(<App/>, opts);
pipe(httpResponse);
pipe(logStream); // throws: second pipe
// after — one render per destination
renderToPipeableStream(<App/>, opts).pipe(httpResponse);
renderToPipeableStream(<App/>, opts).pipe(logStream); Defensive patterns
Strategy: validation
Validate before calling
export function pipeOnce(request) {
let piped = false;
return {
pipe(destination) {
if (piped) throw new Error('pipe() already called — render again for another destination');
piped = true;
return request.pipe(destination);
},
abort(reason) {
request.abort(reason);
},
};
} Prevention
- Call pipe exactly once per renderToPipeableStream result
- Render again for each additional destination instead of re-piping
- Tee at the transport layer (forward chunks) if you must duplicate output
When it happens
Trigger: Calling pipe() twice on one result of renderToPipeableStream — piping to the HTTP response and then also to a cache/log stream, retry logic that re-pipes after a failure, or both a request handler and a shutdown hook calling pipe on the same handle.
Common situations: Frameworks that want to tee the payload (response plus prefetch cache); error-recovery middleware that re-pipes; tests piping one render into several sinks.
Related errors
- React currently only supports piping to one writable stream.
- React currently only supports piping to one writable stream.
- react-dom/server is not supported in React Server Components
- 417
- 417
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/12feaaf31b703bca.
Report an issue: GitHub.