TypeError: Response body object should not be disturbed or locked
I get the TypeError message in this line here: https://github.com/fedify-dev/express/blob/0cba7a08a406bc3263b4055f0fc534b554af1459/src/index.ts#L82
I am running Express inside an AWS Lambda, using @codegenie/serverless-express as a wrapper.
When someone posts something to the Fedify inbox, the Lambda crashes with this error message. This does not happen on my dev computer, only when I run Fedify inside the Lambda function:
TypeError: Response body object should not be disturbed or locked
at extractBody (node:internal/deps/undici/undici:5325:17)
at new Request (node:internal/deps/undici/undici:9499:48)
at fromERequest (file:///opt/nodejs/node_modules/@fedify/express/dist/index.js:52:10)
at file:///opt/nodejs/node_modules/@fedify/express/dist/index.js:5:21
at Layer.handle [as handle_request] (/opt/nodejs/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/opt/nodejs/node_modules/express/lib/router/index.js:328:13)
at /opt/nodejs/node_modules/express/lib/router/index.js:286:9
at Function.process_params (/opt/nodejs/node_modules/express/lib/router/index.js:346:12)
at next (/opt/nodejs/node_modules/express/lib/router/index.js:280:10)
at Function.handle (/opt/nodejs/node_modules/express/lib/router/index.js:175:3)
It's probably the Readable.toWeb() which I don't think forks the stream. Though worth double checking: what node.js version are you using on lambda?
A cursory look suggests that that package may be doing something funky with the request: https://github.com/CodeGenieApp/serverless-express/blob/mainline/src/request.js
I added support for NestJS(@fedify/nestjs) based on @fedify/express, and I got same problem.
I think, It is similar to this issue and it was solved by this PR. In this case, it was caused from Firebase Function
For @fedify/nestjs, Just replacing Readable.toWeb(req) to req.body worked. But, I am analyzing why this works and I don't know it could be applied to @fedify/express, too
I think you might be on the money there with that PR you linked @malkoG, however, it depends if the serverless-express package provides you such.
Looking deeper into that package, it looks like the body comes from the event, so is probably a string here: https://github.com/CodeGenieApp/serverless-express/blob/mainline/src/event-sources/aws/api-gateway-v2.js#L42
So you could do something like:
typeof req.body === 'string' ? req.body : Readable.toWeb(req)
or potentially:
function getBody(req) {
if (typeof req.body === 'string') {
return new ReadableStream({
start(controller) {
controller.enqueue(req.body)
controller.close()
},
})
} else {
return Readable.toWeb(req)
}
}