payload icon indicating copy to clipboard operation
payload copied to clipboard

Next.js and Payload API route error: Response body object should not be disturbed or locked

Open 58bits opened this issue 2 years ago • 0 comments

Link to reproduction

https://github.com/infonomic/payload-custom-server

Describe the Bug

In both the Payload custom server example, and the current website template and when using Next.js App router, if there is an 'api' route handler in Next.js - for example...

.
├── layout.tsx
├── api
│   └── set-theme
│       └── route.ts
└── page.tsx

.. and the route handler is a POST, PUT, PATCH request with a body payload, then Next.js will throw the following error:

TypeError: Response body object should not be disturbed or locked
    at extractBody (node:internal/deps/undici/undici:4323:17)
    at new _Request (node:internal/deps/undici/undici:5272:48)
    at new NextRequest (/payload-custom-server/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/src/server/web/spec-extension/request.ts:24:10)
    at Function.fromNodeNextRequest (/payload-custom-server/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/src/server/web/spec-extension/adapters/next-request.ts:98:12)

The error is being caused because of the shared /api route prefix between Payload and Next.js.

With Payload routes / init registered first, Payload middleware is being applied before the route is rejected, and passed on to Next.js - which then errors as above because the body stream has already been read by Payload (which is what undici is complaining about).

The current 'fix' or workaround, is to either rename the /api path prefix in Payload via payload.config.ts and the routes option, for example...

routes: {
  admin: '/admin',
  api: '/papi',
},

Or to rename the api folder (which is there by convention) inside the Next.js App router app folder - for example from api to napi

.
├── layout.tsx
├── napi
│   └── set-theme
│       └── route.ts
└── page.tsx

To Reproduce

The repo above includes two buttons with onClick handlers on a /test-page route that will call test POST and test GET route handlers in Next.js.

Remove the 'fix' from payload.config.ts - i.e. rename the Payload api path prefix back to /api and then run the project pnpm install pnpm dev

When you visit /test-page - and click on the 'Test POST API Call' button you'll see the error.

Payload Version

2

Adapters and Plugins

No response

58bits avatar Dec 30 '23 17:12 58bits