nextjs - ✅(Solved) Fix Server actions fail to return specific binary files: ‘Cannot perform Construct on a detached ArrayBuffer’ error [14 pull requests, 4 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#84858Fetched 2026-04-08 02:18:07
View on GitHub
Comments
4
Participants
3
Timeline
24
Reactions
0
Timeline (top)
labeled ×5commented ×4mentioned ×4subscribed ×4

Error Message

GET / 200 in 63ms ⨯ [Error: failed to pipe response] { [cause]: [Error: failed to write chunk to response] { [cause]: TypeError: Cannot perform Construct on a detached ArrayBuffer at new Uint8Array (<anonymous>) } } ⨯ [Error: failed to pipe response] { page: '/', [cause]: [Error: failed to write chunk to response] { [cause]: TypeError: Cannot perform Construct on a detached ArrayBuffer at new Uint8Array (<anonymous>) } } TypeError: Cannot perform Construct on a detached ArrayBuffer at new Uint8Array (<anonymous>)

Fix Action

Fixed

PR fix notes

PR #34849: [Flight] Fix detached ArrayBuffer error when streaming typed arrays

Description (problem / solution / changelog)

Using renderToReadableStream in Node.js with binary data from fs.readFileSync (or Buffer.allocUnsafe) could cause downstream consumers (like compression middleware) to fail with "Cannot perform Construct on a detached ArrayBuffer".

The issue occurs because Node.js uses an 8192-byte Buffer pool for small allocations (< 4KB). When React's VIEW_SIZE was 2KB, files between ~2KB and 4KB would be passed through as views of pooled buffers rather than copied into currentView. ByteStreams (type: 'bytes') detach ArrayBuffers during transfer, which corrupts the shared Buffer pool and causes subsequent Buffer operations to fail.

Increasing VIEW_SIZE from 2KB to 4KB ensures all chunks smaller than 4KB are copied into currentView (which uses a dedicated 4KB buffer outside the pool), while chunks 4KB or larger don't use the pool anyway. Thus no pooled buffers are ever exposed to ByteStream detachment.

This adds 2KB memory per active stream, copies chunks in the 2-4KB range instead of passing them as views (small CPU cost), and buffers up to 2KB more data before flushing. However, it avoids duplicating large binary data (which copying everything would require, like the Edge entry point currently does in typedArrayToBinaryChunk).

Related issues:

Changed files

  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js (modified, +36/-3)
  • packages/react-server/src/ReactServerStreamConfigEdge.js (modified, +6/-9)
  • packages/react-server/src/ReactServerStreamConfigNode.js (modified, +5/-1)

PR #85072: Upgrade React from 1324e1bb-20251016 to 58bdc0bb-20251019

Description (problem / solution / changelog)

diff facebook/[email protected]

<details> <summary>React upstream changes</summary> </details>

fixes #84753 fixes #84858

Changed files

  • package.json (modified, +16/-16)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js (modified, +3/-3)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js (modified, +3/-3)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js (modified, +3/-3)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js (modified, +9/-9)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js (modified, +8/-8)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js (modified, +16/-16)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js (modified, +15/-15)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom-experimental/package.json (modified, +2/-2)
  • packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js (modified, +5/-5)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js (modified, +3/-3)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js (modified, +3/-3)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js (modified, +3/-3)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js (modified, +9/-9)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js (modified, +8/-8)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js (modified, +16/-16)
  • packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js (modified, +15/-15)
  • packages/next/src/compiled/react-dom/cjs/react-dom.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-dom/package.json (modified, +2/-2)
  • packages/next/src/compiled/react-experimental/cjs/react.development.js (modified, +24/-6)
  • packages/next/src/compiled/react-experimental/cjs/react.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js (modified, +24/-6)
  • packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js (modified, +1/-1)
  • packages/next/src/compiled/react-is/package.json (modified, +1/-1)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js (modified, +4/-2)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.edge.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js (modified, +6/-7)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js (modified, +5/-6)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.development.js (modified, +48/-49)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.production.js (modified, +11/-11)
  • packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json (modified, +2/-2)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js (modified, +4/-2)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js (modified, +8/-9)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js (modified, +5/-6)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js (modified, +48/-49)
  • packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.js (modified, +11/-11)
  • packages/next/src/compiled/react-server-dom-turbopack/package.json (modified, +2/-2)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js (modified, +4/-2)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.edge.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.unbundled.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js (modified, +6/-7)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js (modified, +5/-6)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.development.js (modified, +48/-49)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.production.js (modified, +11/-11)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.development.js (modified, +48/-49)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.production.js (modified, +11/-11)
  • packages/next/src/compiled/react-server-dom-webpack-experimental/package.json (modified, +2/-2)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js (modified, +4/-2)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js (modified, +2/-0)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (modified, +8/-9)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js (modified, +5/-6)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js (modified, +48/-49)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.js (modified, +11/-11)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js (modified, +48/-49)
  • packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.js (modified, +11/-11)
  • packages/next/src/compiled/react-server-dom-webpack/package.json (modified, +2/-2)
  • packages/next/src/compiled/react/cjs/react.development.js (modified, +24/-6)
  • packages/next/src/compiled/react/cjs/react.production.js (modified, +1/-1)
  • packages/next/src/compiled/react/cjs/react.react-server.development.js (modified, +24/-6)
  • packages/next/src/compiled/react/cjs/react.react-server.production.js (modified, +1/-1)
  • packages/next/src/compiled/unistore/unistore.js (modified, +1/-1)
  • pnpm-lock.yaml (modified, +564/-564)

Code Example

GET / 200 in 63ms
[Error: failed to pipe response] {
  [cause]: [Error: failed to write chunk to response] {
    [cause]: TypeError: Cannot perform Construct on a detached ArrayBuffer
        at new Uint8Array (<anonymous>)
  }
}
[Error: failed to pipe response] {
  page: '/',
  [cause]: [Error: failed to write chunk to response] {
    [cause]: TypeError: Cannot perform Construct on a detached ArrayBuffer
        at new Uint8Array (<anonymous>)
  }
}
TypeError: Cannot perform Construct on a detached ArrayBuffer
    at new Uint8Array (<anonymous>)

---

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.0.0: Mon Aug 25 21:17:56 PDT 2025; root:xnu-12377.1.9~3/RELEASE_ARM64_T6030
  Available memory (MB): 18432
  Available CPU cores: 12
Binaries:
  Node: 20.11.0
  npm: 10.5.0
  Yarn: 1.22.21
  pnpm: 8.15.4
Relevant Packages:
  next: 15.5.5 // Latest available version is detected (15.5.5).
  eslint-config-next: N/A
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.9.3
Next.js Config:
  output: N/A

---

node:buffer:634
write: (buf, string, offset, len) => buf.utf8Write(string, offset, len),
^
RangeError: "offset" is outside of buffer bounds
at Object.write (node:buffer:634:46)
at fromStringFast (node:buffer:463:22)
at fromString (node:buffer:487:51)
at Function.from (node:buffer:297:12)
at console.<anonymous> (/opt/rust/nodejs.js:6:121)
at process.<anonymous> (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:14:40750)
at process.emit (node:events:536:35)
at process._fatalException (node:internal/process/execution:188:25) {
code: 'ERR_BUFFER_OUT_OF_BOUNDS'
}
Node.js v20.19.4
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/niels-bosman/next-server-action-binary-bug-reproduction

To Reproduce

  1. Clone this repository: https://github.com/niels-bosman/next-server-action-binary-bug-reproduction
  2. Run bun install
  3. Go to /
  4. Refresh and see the dev server crash

Current vs. Expected behavior

When returning binary data from a server action (either by reading a file via fs or fetching binary data from a Prisma database row), the response consistently fails for certain files. The underlying cause within those specific binary files is unclear.

In a minimal reproduction case, the issue occurs when reading a particular file from the filesystem and returning its bytes to the client. Other files work as expected, so the problem seems related to some property of the binary data itself.

Expected behavior:

The server action should successfully return all binary files as byte data without error.

Actual behavior:

For specific binary files, the request fails consistently with the following error in the server logs:

GET / 200 in 63ms
 ⨯ [Error: failed to pipe response] {
  [cause]: [Error: failed to write chunk to response] {
    [cause]: TypeError: Cannot perform Construct on a detached ArrayBuffer
        at new Uint8Array (<anonymous>)
  }
}
 ⨯ [Error: failed to pipe response] {
  page: '/',
  [cause]: [Error: failed to write chunk to response] {
    [cause]: TypeError: Cannot perform Construct on a detached ArrayBuffer
        at new Uint8Array (<anonymous>)
  }
}
TypeError: Cannot perform Construct on a detached ArrayBuffer
    at new Uint8Array (<anonymous>)

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.0.0: Mon Aug 25 21:17:56 PDT 2025; root:xnu-12377.1.9~3/RELEASE_ARM64_T6030
  Available memory (MB): 18432
  Available CPU cores: 12
Binaries:
  Node: 20.11.0
  npm: 10.5.0
  Yarn: 1.22.21
  pnpm: 8.15.4
Relevant Packages:
  next: 15.5.5 // Latest available version is detected (15.5.5).
  eslint-config-next: N/A
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Server Actions, Turbopack

Which stage(s) are affected? (Select all that apply)

next dev (local), next start (local), Vercel (Deployed)

Additional context

The file is a gzipped version of the JSON file also included In the repository.

The error sometimes happens on Vercel with these error logs:

node:buffer:634
write: (buf, string, offset, len) => buf.utf8Write(string, offset, len),
^
RangeError: "offset" is outside of buffer bounds
at Object.write (node:buffer:634:46)
at fromStringFast (node:buffer:463:22)
at fromString (node:buffer:487:51)
at Function.from (node:buffer:297:12)
at console.<anonymous> (/opt/rust/nodejs.js:6:121)
at process.<anonymous> (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:14:40750)
at process.emit (node:events:536:35)
at process._fatalException (node:internal/process/execution:188:25) {
code: 'ERR_BUFFER_OUT_OF_BOUNDS'
}
Node.js v20.19.4

extent analysis

TL;DR

The issue can be resolved by properly handling binary data in server actions, potentially by using a library or method that correctly handles ArrayBuffer and Uint8Array conversions.

Guidance

  • Verify that the binary data is being read and written correctly, ensuring that the ArrayBuffer is not being detached prematurely.
  • Check the documentation for the fs and Prisma libraries to ensure that binary data is being handled correctly.
  • Consider using a library like buffer or uint8arrays to handle binary data conversions and avoid errors like "Cannot perform Construct on a detached ArrayBuffer".
  • Test the server action with different types of binary files to identify if the issue is specific to certain file types or sizes.

Example

No specific code example can be provided without modifying the original code, but ensuring that binary data is handled correctly using libraries like buffer or uint8arrays can help resolve the issue.

Notes

The issue seems to be related to the handling of binary data in server actions, and resolving it may require changes to how the data is read, written, and converted between different formats.

Recommendation

Apply a workaround by using a library that correctly handles binary data conversions, such as buffer or uint8arrays, to avoid errors like "Cannot perform Construct on a detached ArrayBuffer" and "ERR_BUFFER_OUT_OF_BOUNDS".

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix Server actions fail to return specific binary files: ‘Cannot perform Construct on a detached ArrayBuffer’ error [14 pull requests, 4 comments, 3 participants]