{"record":{"id":"e2998ba98eb47865","repo":"facebook/react","slug":"react-currently-only-supports-piping-to-one-writab-e2998b","errorCode":null,"errorMessage":"React currently only supports piping to one writable stream.","messagePattern":"React currently only supports piping to one writable stream\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-server-dom-parcel/src/server/ReactFlightDOMServerNode.js","lineNumber":217,"sourceCode":"    options ? options.identifierPrefix : undefined,\n    options ? options.temporaryReferences : undefined,\n    options ? options.startTime : undefined,\n    __DEV__ && options ? options.environmentName : undefined,\n    __DEV__ && options ? options.filterStackFrame : undefined,\n    debugChannelReadable !== undefined,\n  );\n  let hasStartedFlowing = false;\n  startWork(request);\n  if (debugChannelWritable !== undefined) {\n    startFlowingDebug(request, debugChannelWritable);\n  }\n  if (debugChannelReadable !== undefined) {\n    startReadingFromDebugChannelReadable(request, debugChannelReadable);\n  }\n  return {\n    pipe<T: Writable>(destination: T): T {\n      if (hasStartedFlowing) {\n        throw new Error(\n          'React currently only supports piping to one writable stream.',\n        );\n      }\n      hasStartedFlowing = true;\n      startFlowing(request, destination);\n      destination.on('drain', createDrainHandler(destination, request));\n      destination.on(\n        'error',\n        createCancelHandler(\n          request,\n          'The destination stream errored while writing data.',\n        ),\n      );\n      // We don't close until the debug channel closes.\n      if (!__DEV__ || debugChannelReadable === undefined) {\n        destination.on(\n          'close',\n          createCancelHandler(request, 'The destination stream closed early.'),","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-server-dom-parcel/src/server/ReactFlightDOMServerNode.js#L199-L235","documentation":"react-server-dom-parcel's renderToPipeableStream returns a pipeable handle guarded by a hasStartedFlowing flag. Once pipe(destination) is called, the Flight request starts flushing rows to that single Node Writable. React throws on any second pipe() call because interleaving the same request's rows into two streams would corrupt the RSC protocol stream.","triggerScenarios":"Calling pipe() twice on the same handle returned by renderToPipeableStream: piping once to the http.ServerResponse and again to a cache write-stream, or re-piping to a fresh response after a client disconnect/abort retry.","commonSituations":"SSR error handlers that swap destinations mid-stream; middleware wanting to tee the RSC payload for logging or edge caching; retry loops that call pipe(res) again after backpressure or a socket error.","solutions":["Call renderToPipeableStream() again to create a new request for each additional destination instead of reusing one handle","If you need the same output in two places, pipe once into a stream.PassThrough and fan out from that","When you must replay the payload (caching), buffer the render first (renderToBuffer/string) and then write it to each destination"],"exampleFix":"// before\nconst {pipe} = renderToPipeableStream(<App />, options);\npipe(res);\npipe(cacheStream); // Error: only one writable stream\n\n// after\nconst {pipe} = renderToPipeableStream(<App />, options);\npipe(res);\nconst {pipe: pipeToCache} = renderToPipeableStream(<App />, options);\npipeToCache(cacheStream); // separate render per destination","handlingStrategy":"validation","validationCode":"const {pipe} = renderToPipeableStream(<App />, options);\nlet piped = false;\nfunction pipeOnce(destination) {\n  if (piped) {\n    throw new Error('Stream already piped; create a new render instead.');\n  }\n  piped = true;\n  return pipe(destination);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat the pipeable handle as single-use; never put pipe() inside retry loops","Create one renderToPipeableStream call per destination","Wrap framework stream helpers to assert a not-yet-piped invariant before delegating"],"tags":["react-server-components","parcel","node-streams","ssr","render-to-pipeable-stream"],"backgroundTag":"stream-already-consumed","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}