Jest Games
Jest Games

Reputation: 455

Variable "$file" got invalid value {}; Upload value invalid

I am using GraphQLClient from graphql-request to send requests to my server. I am trying to upload a file by doing the following:

const graphQLClient = new GraphQLClient('http://localhost:4000/graphql', {
    credentials: 'include',
    mode: 'cors',
});
const source = gql`
    mutation uploadImage($file: Upload!) {
        uploadImage(file: $file)
    }
`;
const file: RcFile = SOME_FILE; // RcFile (from antd) extends File
await graphQLClient.request<{uploadImage: boolean}>(source, { file });

However, when I send a request to my server this way I get the following error:

GraphQLError: Variable \"$file\" got invalid value {}; Upload value invalid

This is what my request looks like in the console:

operations: {
    "query":"\n mutation uploadProfileImage($file: Upload!){\n uploadProfileImage(file: $file)\n }\n",  
    "variables":{"file":null}
}
map: {"1":["variables.file"]}
1: (binary)

Has anyone else had this issue? I can't seem to upload a file to my backend.

Upvotes: 10

Views: 11156

Answers (4)

Joe Seifi
Joe Seifi

Reputation: 1705

In addition, try to make sure csrfPrevention is not set to true in your ApolloServer config

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    csrfPrevention: false, // if this is set to true, uploads will fail
    uploads: false,
    cache: "bounded",
    plugins: [ApolloServerPluginLandingPageLocalDefault({ embed: true })],
  });

Upvotes: -1

Shadee Merhi
Shadee Merhi

Reputation: 333

In addition to the ApolloServer implementation described in the accepted answer (and to clarify @Masoud 's answer), make sure you also have the following client implementation using apollo-upload-client:

import { ApolloClient, InMemoryCache } from "@apollo/client";
import { createUploadLink } from 'apollo-upload-client';

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: createUploadLink({
      uri: 'http://localhost:4000/graphql'
  }),
});

Upvotes: 1

Masoud
Masoud

Reputation: 342

it depends on ApolloClient that you used.

1- If used import { ApolloClient } from 'apollo-client' must be used "createUploadLink" instead of "createHttpLink "means,

import { createUploadLink } from 'apollo-upload-client'
const httpLink = createUploadLink({
  uri: httpEndpoint,
})

2- if used createApolloClient, exact this package:

import { createApolloClient, restartWebsockets } from 'vue-cli-plugin-apollo/graphql-client'
const { apolloClient, wsClient } = createApolloClient({
    ...defaultOptions,
    ...options,
  })
``
You do not need to set anything and Upload work complete.

Upvotes: 1

Jest Games
Jest Games

Reputation: 455

I fixed the issue by setting the uploads option to false in the ApolloServer configuration.

new ApolloServer({ schema, context, uploads: false })

And then using the graphqlUploadExpress() middleware from graphql-upload.

app.use(graphqlUploadExpress({ maxFileSize: 10000, maxFiles: 10 }));

Hopefully this helps anyone who runs into the same issue I did 😊

Upvotes: 14

Related Questions