apollo-server: Calling createReadStream() for uploaded file crashes in NodeJS 13
Running in NodeJS 13.1.0:
const { createReadStream, filename } = await file // uploaded file
const stream = createReadStream()
Result:
RangeError: Maximum call stack size exceeded
at _openReadFs (internal/fs/streams.js:1:1)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open (D:\db-server\node_modules\fs-capacitor\lib\index.js:90:11)
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 70
- Comments: 53 (9 by maintainers)
Commits related to this issue
- Added workaround for https://github.com/apollographql/apollo-server/issues/3508 Fixes #2101. Currently, apollo-server-express depends on apollo-server-core which depends on graphql-upload ^8.0.2. gr... — committed to Vultraz/keystone-5 by Vultraz 4 years ago
- Disable file-upload tests on Node.js 14. Node.js 14 is not LTS yet, but we want to make sure that we're preparing for and breaking changes that it brings. We can't support uploads on Node.js 14 befo... — committed to apollographql/apollo-server by abernix 4 years ago
- Switch to a manual graphql-upload setup. This allows the current graphql-upload version to be used instead of the outdated version shipped with Apollo Server, which doesn’t support recent Node.js ver... — committed to jaydenseric/apollo-upload-examples by jaydenseric 4 years ago
- downgrade node version to 12 until https://github.com/apollographql/apollo-server/issues/3508 is resolved — committed to coverified/platform_backend by schliflo 4 years ago
- System: * Switch from using build-in Apollo Server "Upload" functionality to making explicit use of graphql-upload. This has been done to work around a defect handling uploads on NodeJS v14. Uploads... — committed to Smithsonian/dpo-packrat by jahjedtieson 3 years ago
- build in apollo-server file upload uses an outdated apollo-upload version: so an Maximum call stack size exceeded error occurs. -> solved as suggested: https://github.com/apollographql/apollo-server/i... — committed to ichrist97/msp_backend by DanBilic 3 years ago
I know a lot of people are looking to be un-blocked here, so I want to offer this update and some instructions I put together as a suggestion, in hopes that it can be validated and that it works for those that need answers today, but also as a proof of concept for how we hope it will work in the future.
At a high level, while we believe that
graphql-upload
has provided tremendous value, we believe that the package itself stands really well on its own (see it’s own repository for the details, including the specification that supports it). It has been architected in a way where it can be added to a GraphQL server and doesn’t need to be baked into Apollo Server to function. Continuing along those lines, we think it will be able to serve the community if it is not closely coupled / bundled into Apollo Server as a direct dependency (and enabled by default).In Apollo Server 3.0, we will not ship
graphql-upload
(or upload support) by default. While there are a number of ways to do uploads, thegraphql-upload
package is not the only way to do it. Some other suggestions have been outlined on our blog.. As for Apollo Server 2.x: due to (necessary) breaking changes in newer versions (see https://github.com/apollographql/apollo-server/pull/4039), the version ofgraphql-upload
that exists today will not be updated further. (Semantically version speaking: the update would require a bump to v3, but we already plan on de-coupling it in v3.)As for today / now: Anyone who wants to use a newer version of
graphql-upload
today, please try using the package’s own installation instructions, rather than using the baked-in Apollo Server version ofgraphql-upload
.Switch from using
apollo-server
to one of the Apollo Server integration packages, likeapollo-server-express
.This is necessary because
apollo-server
(which usesapollo-server-express
internally) doesn’t expose it’s HTTP server directly. If switching to the Express integration, this should be as simple as creating your own Express application:And then replacing the existing (roughly)
server.listen(ListenOpts).then(OnListeningCallback)
call with:…taking care to maintain the
ListenOpts
andOnListeningCallback
as they were before, but in the new locations (note: not aPromise
chain!)Disable the upload support provided by the older
graphql-upload
version included in Apollo Server 2.x by settinguploads: false
on theApolloServer
constructor’s “options”Install the latest version of
graphql-upload
Import the necessary primitives from
graphql-upload
into the module whereapplyMiddleware
is calledAdd the
Upload
scalar to the schema by adding to thetypeDefs
SDL appropriately.Add a resolver for the
Upload
scalarAdd the
graphql-upload
middlewareAdd the
graphqlUploadExpress
middleware before calling into theApolloServer
instance’sapplyMiddleware
method with theapp
:And I think that should do it. I really hope this helps! While this does add a few lines of boiler-plate when you need uploads, it’s only a few lines.
If someone could try it out, it’d be greatly appreciated if it could be validated! Thanks!
This seems like a pretty serious bug. I’m surprised that it is still open…
It’s been almost a year since this issue has been created. Very disappointed that this is still not resolved. Considering the lack of maintenance I’m not quite sure if
apollo-server
is still the way to go.A fix in my case was to force a version pf graphql-upload:
in your package.json add this:
If you are using yarn, that should work. npm users should add this to their “scripts” in package.json:
"preinstall": "npx npm-force-resolutions"
Then run
npm install
. You do need a lockfile for it to work.graphql-upload 9.0.0 is out with node 13 support
This seems to be a problem with an older version of fs-capacitor
According to https://github.com/jaydenseric/graphql-upload/issues/170 the fix is checked in to master already and awaiting publish soon
until then, merging this into package.json will work. The preinstall script is only needed if using npm, as yarn supports dependencies natively
Thanks 👍 Shocking that they still haven’t fixed this officially
Isn’t it about time to fix this? Node v14 is out with release status LTS, and here we are still finding support for v13 😕
I downgraded to Node 12 and worked.
This WORK perfectly!!! Don’t scroll more here the answer!!
Still crashing on v14
None of the solutions worked for me. The resolutions fix and the graphql manual update didn’t work as I’m using apollo-server-lambda. Downgrading my node version to 12 just so I can get apollo working does not seem like a reasonable thing to do. I guess I’m on an island here.
This bug is really a blocker for this module and should be considered top priority for maintainers.
A workaround is to force resolution for module graphql-upload to a more recent version :
in package.json
be aware that resolutions property is currently only handled by yarn package manager, not by npm
with npm, you have to preinstall an aditionnal module to force resolutions :
of cours, check that your CI support preinstall scripts (our don’t)
@abernix I don’t know if this is feasible, but did you consider releasing the breaking change fix on v3, while the upcoming planned release be v4?
facing same issue with node 14x
I have the same problem with node 14x
@laooola I’m with you here. With 2.x being the only “stable” version available, it’s weird not to see core deps be updated anymore, especially when version 3 literally could be a year away.
Thanks!
Half a year passed since I opened this issue and no response from maintainers. I consider switching to https://github.com/mcollina/fastify-gql which is significantly faster , supports subscriptions and have built-in support for loaders
Same here, downgrading to 12.
I am having the sam issue, but only when app is in production. @lynxtaa did you find any workaround?
Thanks a lot @glasser for this detailled explanation. We plan to implement direct use of
graphql-upload
as you explained, thx.However I see that all the issues related the the incompatibility with node 13 are closed with a link to the version 2.21 of appolo-server-express.
I fail to see how version 2.21 is related to this very problem : version 2.21 allows as of now to use graphql@15, but is still incompatible with node 14 (as you have confirmed above).
It was not clear for me what the current situation was (because I don’t know what you have modified in your fork of graphql-upload version 8) and I suspect many users of this module are confused as well. I think the most important part here is “This is essentially closed as WONTFIX” and should be mentionned in the readme, because newcomers with this library or users migrating from node <13 are likely to run into the same issue as well.
And thx again for all your work on this library 👍
I’m gonna roll this one into #4865 too. I hope to make some rapid progress on this soon.
This seems to work in Node.js v15.0.1. However, the following warning pops up:
Adding this here in case it helps someone else.
After trying everything listed above I couldn’t get it to work (even on Node 12??). Anyways I discovered I had
graphql-upload
in mynode_modules
, butapollo-server-core
had its own and was using that one. Updating THAT one (just by FTP) has fixed it.Far from a perfect solution, but ¯_(ツ)_/¯
@abenhamdine This is essentially closed as WONTFIX.
Upgrading the version of
graphql-upload
that Apollo Server 2 relies on in order to support Node 14 would require taking other backwards-incompatible changes fromgraphql-upload
, which we aren’t comfortable doing within the single major version of AS2.On the other hand, the plan for AS3 is not to upgrade
graphql-upload
but to disentangle it from AS entirely and encourage folks to usegraphql-upload
directly; the role of AS3 here will be to provide whatever hooks are necessary for users to add arbitrary versions ofgraphql-upload
to their app rather than to bundle a specific version.I encourage you to use
graphql-upload
directly in your app (passuploads: false
tonew ApolloServer
and just usegraphql-upload
as described in its docs).My guess is that this will work fine with, say, apollo-server-express, but that this will be challenging for apollo-server-lambda because there’s no “middleware” there to let you inject the call to
graphql-upload
. So somebody interested in getting that working should come up with a good hook or two to add toapollo-server-lambda
in order to integrategraphql-upload
.Note that I just landed a PR to rewrite
apollo-server-lambda
to be an async function (and to inline the oldgraphqlLambda
function) which I think will make it a lot easier to add integration points, as the old code structure was quite hard to follow.This solved my problem
I’m moving to
express-graphql
since this is a blocker for me and it appears to be unresolved.Working fine with this Node version.
Actually, this doesn’t fix the error in my case…
Any case like me? Any other solutions rather than downgrading to Node v12 ?
My Node version is v.14.9.0
Yes, as mentioned, I don’t think there’s currently a great solution for integrating a non-built-in use of
graphql-upload
withapollo-server-lambda
.AS3 is going to remove the built-in
graphql-upload
. I think it would be great if, before AS3, we had a way to usegraphql-upload
withapollo-server-lambda
that isn’t the built-in integration! That probably involves looking at howapollo-server-lambda
works, seeing where thegraphql-upload
integration gets slotted in, and adding a more generic integration point that doesn’t have to begraphql-upload
-specific.I’m the new lead maintainer of AS but I have to admit — I don’t use lambda myself, and we don’t use it much internally at Apollo. My philosophy is that while
apollo-server-lambda
is quite important (it’s the second most downloaded AS flavor, though the gap between it and Express is huge), it’s best for improvements toapollo-server-lambda
to be driven by folks who actually use it themselves in practice rather than by folks like me who are mostly learning Lambda on the fly.So what I’d love to see happen is a PR from somebody in the community that allows you to slot in the newest release of
graphql-upload
directly intoapollo-server-lambda
without tying the implementations directly to each other. Then we can get that into a v2 minor release, and so when v3 comes out without the built-in graphql-upload integration it doesn’t actually remove any functionality.Taking a quick glance at
apollo-server-lambda/ApolloServer.ts
, it looks like it defines afileUploadHandler
function takes in anext
function and closes over (and mutates!)event
. So it seems like we could add a new option tonew ApolloServer
that’s likelambdaPreGraphQLMiddleware: (event: APIGatewayProxyEvent, next: Function) => something
which if provided gets called beforefileUploadHandler
. And then there would hopefully be a simple way to pluggraphql-upload
into thatlambdaMiddleware
function (while also passinguploads: false
).The function also closes over
response
but looks like that’s just an elaborate way of being able to triggergraphql-upload
’s cleanup. So probably there should be a secondlambdaPostGraphQLMiddleware
hook where you can invokeresponse.end()
rather than that being part of the first middleware.I’d love to review a PR that’s something like this! Of course I’m not a Lambda expert so there might be some other much more natural way of implementing this. But basically: let’s come up with some non-upload-specific hooks that let you use upstream
graphql-upload
withapollo-server-lambda
, and let’s get that into AS2!We are never going to upgrade graphql-upload in Apollo Server v2, and we are going to remove the built-in integration from Apollo Server v3. That’s not to say that we don’t like graphql-upload: we just think folks should be able to get every new improvement @jaydenseric puts out without needing to tightly couple it to the Apollo Server release cycle. Folks who want to use the newer version of graphql-upload now should follow @abernix 's suggestion in https://github.com/apollographql/apollo-server/issues/3508#issuecomment-662371289 to disable the built-in integration and install the
graphql-upload
version of your choice.I recognize that there may be some integrations (eg Lambda) where there’s no easy place to plug in the graphql-upload processRequest function. If that’s the case, we can fix that by adding an appropriate hook to the integration that would allow you to insert processRequest (or any handler of your choice!) at the right place, without tightly coupling the implementation to graphql-upload.
I have the same issue, I tried on Node.js v15.0.1 with the latest graphql-upload and fs-capacitor and the file seems to arrive but when I pipe it to a WriteStream and try to write it to the disk It is empty.
The only workaround that I found after hours of trying is to use Node v12.19.0 😦.
Having the same issue. However check this workaround instead of downgrading: https://github.com/MichalLytek/type-graphql/issues/37#issuecomment-592467594 more specifically for people using type-graphql.
@safead For me it showed up in production build inside docker containers, downgrading node to the last LTS helped
FROM node:12.16.1