Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when processing uploads after upgrading to v10 #185

Closed
MaissonTi opened this issue Jan 31, 2020 · 23 comments
Closed

Error when processing uploads after upgrading to v10 #185

MaissonTi opened this issue Jan 31, 2020 · 23 comments

Comments

@MaissonTi
Copy link

I'm testing graphql-upload with graphql-relay / mutationWithClientMutationId. However, the return value is {}

Any solution?

mutation

Altair

@jaydenseric
Copy link
Owner

Most likely the client is not sending a GraphQL multipart request. Check your network activity for the GraphQL request being sent from the client to see if it a multipart request or not.

I'm not sure the best way to configure your particular GraphQL client so that it detects files are used in variables, in order to conditionally send a normal GraphQL POST request or the special multipart request.

@RyannGalea
Copy link

RyannGalea commented Feb 1, 2020

I get this same issue from upgrading from 9.0.0 to 10.0.0, works great in 9.0.0 but now with the upgrade to 10.0.0 it fails giving the same error.

I am using Apollo Server

@jz222
Copy link

jz222 commented Feb 3, 2020

I face the same issue. As soon as I upgrade to version 10.0.0 I get the same error message as shown above. After downgrading to version 9.0.0, it works again. I'm also using Apollo Server and Apollo Client with apollo-upload-client.

@mike-marcacci
Copy link
Collaborator

@RyannGalea @jz222 what version of node are you running?

@mike-marcacci mike-marcacci reopened this Feb 3, 2020
@RyannGalea
Copy link

RyannGalea commented Feb 4, 2020

@mike-marcacci

Node: v12.13.1

"apollo": "^2.22.0",
"apollo-server-express": "^2.9.16",
"graphql-upload": "9.0.0",

@jz222
Copy link

jz222 commented Feb 4, 2020

@mike-marcacci

Node: v12.13.1

apollo-server: 2.8.2

@Valandur
Copy link

Valandur commented Feb 4, 2020

I also get the issue with v10, but not v9. (I'm using a setup with NestJS)

When testing the curl file list request manually in the terminal I get the response Variable \"$images\" got invalid value {} at \"images[0]\"; Expected type Upload. Upload value invalid.

If i manually add app.use(graphqlUploadExpress()); (which isn't required with v9, it "just works") I get the response BadRequestError: Missing multipart field ‘operations’ (this might be due to now duplicated middleware?)

@wisekaa03
Copy link

wisekaa03 commented Feb 5, 2020

I face the same issue, with NestJS 6.9 and graphql-upload 10.0.0
I have to downgrade graphql-upload 9.0.0

@szz-dvl
Copy link

szz-dvl commented Feb 7, 2020

Hi!

I'm facing the same issue, I'm using:

apollo-server-express@2.9.16
graphql-upload@10.0.0
node: v13.7.0

I'm sending a file using:

curl localhost:3001/graphql \
  -F operations='{ "query": "mutation ($file: Upload!) { uploadFF(file: $file) { id } }", "variables": { "file": null } }' \
  -F map='{ "0": ["variables.file"] }' \
  -F 0=@a.txt

In the server I'm using type-graphql integration such as:

import { Field, ObjectType } from 'type-graphql';
import { GraphQLUpload, FileUpload } from 'graphql-upload';

@ObjectType()
export class Image {
  constructor(url: string) {
    this.url = url;
  }

  @Field({ nullable: false })
  url: string;
}

@Resolver(Image)
class ImageResolver {

  @Mutation(returns => Image)
   async uploadFF(
    @Arg('file', type => GraphQLUpload)
    { filename, createReadStream, encoding, mimetype }: FileUpload,
  ) {
    console.log(filename);
    return new Image('test');
  }
}

Every time I try to upload an image I'm getting:

GraphQLError: Variable "$file" got invalid value {}; Expected type Upload. Upload value invalid.

Looking in your code I can see, in the file GraphQLUpload.js:

module.exports = new GraphQLScalarType({
  name: 'Upload',

  description: 'The `Upload` scalar type represents a file upload.',

  parseValue(value) {
    if (value instanceof Upload) return value.promise
    throw new GraphQLError('Upload value invalid.')
  },

  parseLiteral(ast) {
    throw new GraphQLError('Upload literal unsupported.', ast)
  },

  serialize() {
    throw new GraphQLError('Upload serialization unsupported.')
  }
})

If I print the value received in parseValue function I can see in my console:

Promise {
    {
       filename: 'a.txt',
       mimetype: 'text/plain',
       encoding: '7bit',
       createReadStream: [Function: createReadStream]
    }
}

So replacing the above mentioned code, the Upload Scalar, by:

module.exports = new GraphQLScalarType({
  name: 'Upload',

  description: 'The `Upload` scalar type represents a file upload.',

  parseValue(value) {
   return value;
  },

  parseLiteral(ast) {
    throw new GraphQLError('Upload literal unsupported.', ast)
  },

  serialize() {
    throw new GraphQLError('Upload serialization unsupported.')
  }
})

Everything is working as expected, however I don't know how to validate the received value, or if I even need to do so ...

Will it be fixed? Can I help any way?

Thanks in advance!

Szz

@mike-marcacci
Copy link
Collaborator

Sorry for the delay here - both @jaydenseric and myself are totally slammed at the moment with our "day jobs." However, I have a suspicion: where are you all getting your Upload scalar? Between v9 and v10 this changed in important ways, and if you aren't using the one exported by v10 I wouldn't be surprised if an error like this would appear.

@szz-dvl
Copy link

szz-dvl commented Feb 7, 2020

@mike-marcacci If you are referring to GraphQLUpload I'm just importing it from your package grapql-upload,

import { GraphQLUpload, FileUpload } from 'graphql-upload';

Must I change it?

Thanks again!

P.D: don't worry about delays, everyone is busy ...

@mike-marcacci
Copy link
Collaborator

@szz-dvl I totally missed your comment up above. So in this case my suspicion is that you do indeed have two versions installed, but in the opposite order I had assumed:

  • It looks like v9 or earlier is actually handling the request;
  • It looks like v10 is what you're using in your own code;

I suspect that Apollo is running v9 here and needs to update. If you're using yarn for package management you can run yarn why graphql-upload to see all currently installed versions and which packages depend on them. If this is in fact the issue, you can use yarn's resolutions to temporarily override the version specified by Apollo, assuming the version is compatible.

@mike-marcacci mike-marcacci changed the title Not upload file Error when processing uploads after upgrading to v10 Feb 7, 2020
@szz-dvl
Copy link

szz-dvl commented Feb 7, 2020

Hey!

Did as you suggested, working properly now!

Really appreciated!

Szz.

@jaydenseric
Copy link
Owner

For anyone having problems after upgrading to v10, try running npm ls graphql-upload. If you see multiple versions installed, that is the problem; you need to be using one version in your project.

Apollo Server uses an old graphql-upload version as a dependency, so you’re stuck with whatever version they are using until they upgrade (which usually takes ages), unless you’re keen to hack around. @mike-marcacci has already offered a potential workaround for Apollo Server using an older version using Yarn resolutions. In the past it has been possible to disable Apollo Server’s built in file upload features and completely set them up in your project from scratch, which is probably what I would do if I still used Apollo instead of graphql-api-koa.

If you are experiencing issues relating to Apollo Server, please raise issues on the Apollo side instead of here, it's on them to keep their dependencies up to date and provide support.

@RyannGalea
Copy link

Is there any current solution for this yet? In regards to apollo-server-express. This is a bit of a pain

@iam4x
Copy link

iam4x commented Jan 12, 2021

Yes @RyannGalea you can add this into your package.json to force graphql-upload to v11 in your dependencies:

  "resolutions": {
    "graphql-upload": "^11.0.0"
  },

Running npm ls graphql-upload will give me:

image

This should fix the issue, the upgrade was seamless after that for me 👍

@akashelhance
Copy link

image

I am graphql upload version 12 and facing this issue.

@vorant94
Copy link

vorant94 commented May 31, 2021

for everyone who might face it using Apollo with NestJS it seems that new versions of apollo-server-express are using their fork of this lib and not lib itself, as a result you cannot use resolutions to force the version you need.

Screen Shot 2021-05-31 at 22 45 13

In the fork description they indeed advised not to depend on their fork straightforward, but disable it by passing uploads: false to new ApolloServer, but in my case it caused to server not being able to parse multipart data at all.

Screen Shot 2021-05-31 at 22 52 36

Since I have possibility to use hybrid REST and Apollo server, I would go for this option for now

@chris-aeviator
Copy link

for everyone who might face it using Apollo with NestJS it seems that new versions of apollo-server-express are using their fork of this lib and not lib itself, as a result you cannot use resolutions to force the version you need.

<
In the fork description they indeed advised not to depend on their fork straightforward, but disable it by passing uploads: false to new ApolloServer, but in my case it caused to server not being able to parse multipart data at all.

Since I have possibility to use hybrid REST and Apollo server, I would go for this option for now

Facing the very same issue :-/

@vorant94
Copy link

vorant94 commented Jun 2, 2021

@chris-aeviator if you have no option to use hybrid app, then the only other solution I found is to use additional middleware before Apollo one like @jaydenseric mentioned so it will catch all files and work with them as you need and won't pass them to regular Apollo.

I guess it was a cause why my app stopped understand multi-part at all: I turned of the build-in one, but didn't add any other

@chris-aeviator
Copy link

chris-aeviator commented Jun 2, 2021

I'm using graphql yoga so I'm unsure howto set this middleware

EDIT:

wait - you say apollo - am I supposed to do this on the client (the uploading frontend)

EDIT2 :
I guess you mean apollo server here, will check the graphql yoga docs for the middleware

@chris-aeviator
Copy link

I have solved my issue in graphql yoga by

a) setting uploads: false
b) importing graphqlUploadExpress
c) setting

grafik

(using the middlewares setting did not work for me)

@intellix
Copy link

intellix commented Jun 7, 2021

Hate to jump on the bandwagon but also confused as the error doesn't really mean anything:

Error:

message: "Variable \"$input\" got invalid value [{ resolve: [function], reject: [function], promise: {}, file: [Object] }] at \"input.upload\"; Upload value invalid."

Form Data:

operations: {"operationName":"CreateDocument","variables":{"input":{"userId":"VXNlcjo4","type":"IDENTITY","upload":[null]}},"query":"mutation CreateDocument($input: CreateDocumentInput!) {\n  createDocument(input: $input) {\n    document {\n      ...Document\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment Document on Document {\n  id\n  verified\n  createdAt\n  asset {\n    id\n    url\n    fileName\n    fileSize\n    __typename\n  }\n  __typename\n}\n"}
map: {"1":["variables.input.upload.0"]}
1: (binary)

Type Definitions:

input CreateDocumentInput {
  userId: ID!
  type: DocumentType
  upload: Upload
}

npm ls graphql-upload:

/Users/dominicwatson/Projects/api
├─┬ graphql-tools@7.0.4
│ └─┬ @graphql-tools/url-loader@6.8.2
│   └── graphql-upload@11.0.0 
└── graphql-upload@11.0.0

Believe I'm doing everything as explained. Not sure if it conflicts with the other express middlewares?

app.use(
  express.json({
    limit: '10mb',
    type: ['application/json', 'application/vnd.api+json'],
  }),
);
app.use(graphqlUploadExpress());

const httpServer = createServer(app);
const apolloServer = createApolloServer(sessionStore, appConfig.stage);
apolloServer.applyMiddleware({ app, cors: corsConfig });
apolloServer.installSubscriptionHandlers(httpServer);

If I add a breakpoint into the GraphQLUpload resolver, I can see that it sees the file and awaits it:
Screenshot 2021-06-07 at 23 46 01

Sometimes it works.... sometimes it gives that error. At one point I feel like I've fixed it and then another it starts giving the error again.... super random

Edit: Revisited the above and it seems the problem I had was I was uploading an array of files which used to work or be required (not sure). Changing the type to [Upload] fixed it for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests