Uploading images using the Files API - upload fails with "The file does not exist"

JBraund
Tourist
5 1 2

Afternoon folks,

I'm trying to use the new Files API, in concert with the stagedUploadsCreate mutation, to allow our client to upload images through an Admin app that we are creating for them. The image data is going to be coupled to some other custom product metadata, which we'll handle in the background - hence not wanting to use the out-of-the-box Files interface.

I've reviewed this blog post, as well as the Files API release notes and the fileCreate mutation docs, so I think I understand the process correctly:

  1. Use the stagedUploadsCreate mutation to upload the file metadata (name, type, size), and receive an upload URL and metadata parameters
  2. Use the URL and metadata params from the stagedUploadsCreate response to upload the file to the destination (a Shopify-owned S3 bucket)
  3. Use the fileCreate mutation to create a File (MediaImage) representation of the uploaded image, which will then be available to query and get the Shopify edge-cached URL for

My implementation of this in my React (Typescript) app looks something like this:

 

// given imageFile, which is a File that has been selected by the user using the Polaris DropZone component
const STAGED_UPLOADS_CREATE = gql`
  mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
    stagedUploadsCreate(input: $input) {
      stagedTargets {
        resourceUrl
        url
        parameters {
          name
          value
        }
      }
      userErrors {
        field
        message
      }
    }
  }
`;

const FILE_CREATE = gql`
  mutation fileCreate($files: [FileCreateInput!]!) {
    fileCreate(files: $files) {
      files {
        alt
        createdAt
        ... on MediaImage {
          id
          mediaErrors {
            code
            details
            message
          }
          fileStatus
          status
          image {
            originalSrc
            transformedSrc
          }
        }
      }
      userErrors {
        code
        field
        message
      }
    }
  }
`;

const [
  stagedUploadsCreate,
  { error: stagedUploadsCreateError },
] = useMutation(STAGED_UPLOADS_CREATE);

const [fileCreate, { error: fileCreateError }] = useMutation(FILE_CREATE);

const { data: stagedUploadsCreateData } = await stagedUploadsCreate({
  variables: {
    input: {
      resource: "IMAGE",
      filename: imageFile.name,
      mimeType: imageFile.type,
      fileSize: imageFile.size.toString(),
      httpMethod: "POST",
    },
  },
});
console.log(stagedUploadsCreateData);

const {
  stagedUploadsCreate: {
    stagedTargets: [{ url, parameters, resourceUrl }],
  },
} = stagedUploadsCreateData;

const formData = new FormData();
parameters.forEach(({ name: paramName, value }: any) =>
  formData.append(paramName, value),
);
formData.append("file", imageFile);

await axios.post(url, formData);

const { data: fileCreateData } = await fileCreate({
  variables: {
    files: [{ contentType: "IMAGE", originalSource: resourceUrl }],
  },
});

 

 This all goes fine - I stepped through the network requests, and I get a 201 response code back from the file upload request, and then I can see that the fileCreate mutation runs successfully. In the status field of the returned object, I can see that the status is "UPLOADED".

However, when I go to the Files UI in Shopify Admin, I get the error:

3 files failed to upload
The rest of your files uploaded successfully. View failed files for more details.

(As you might guess, I've tried this with 3 different files so far!)

When I query the files resource via the API to get a closer look, I see the follow response:

shopify-files-error.jpg

As far as I can tell, I'm using the API as intended. Unfortunately, there doesn't seem to be a great deal in the way of documented examples for using this API at the moment. Can anyone point me in the right direction please? I'm sure I'm making some small mistake, but just can't for the life of me figure out what.

Thanks in advance, and have a great day folks!

James.

Replies 8 (8)

JBraund
Tourist
5 1 2

Responding to give this thread a bump.

I've also reached out for support via Shopify Partners live chat, who have told me that they don't have the technical know-how to look into this, and just pointed me back to these forums and the documentation. I've noticed a couple of other comments/threads (here, here) where people are also having problems with this API, which suggests more clarification in general may be needed around this new functionality.

Can anyone help please?

Thanks,

James

JBraund
Tourist
5 1 2

Bumping again.

Can anyone offer any suggestions please?

awwdam
Shopify Staff
249 42 36

Hey @JBraund - I was able to share some insights on uploading a "FILE" (type text/json) using the stagedUploadsCreate mutation, and shared steps and examples in the first forum post you mentioned was related. If you are still have an issue, please feel free to provide an x-request-id header returned from both mutations in the process? It would also help if could provide examples of the RAW API query and variables that your application is generating, as well as the format of your cURL or HTTP request to the S3 bucket where the upload is meant to be staged. I would be happy to take a closer look from there and pass on any insights I can to help! 

awwdam | API Support @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

mariannef
Visitor
2 0 4

Just in case anyone comes across this and the solution is not clear, I got it working by changing the stagedUploadsCreate "resource" variable to FILE instead of IMAGE.

Example:

 

let { data } = await stagedUploadsCreate({
      variables: {
        "input": [
          {
            "resource": "FILE",
            "filename": file.name,
            "mimeType": file.type,
            "fileSize": file.size.toString(),
            "httpMethod": "POST"
          }
        ]
      }
    });

 

  

poberezhets
Shopify Partner
2 0 0

@mariannef You are a life saver! I was able to make it work by changing "IMAGE" to "FILE"

Thank you so much!

Celso_White
Shopify Partner
23 0 23

Thank you! This took so long to debug and figure out.

 

@Shopify - Please make a comprehensive example of how to use this api StagedUploadCreate -> AWS posting -> FileCreate and explain nuances like this. A single article could save a lot of us days of work.

Celso_White
Shopify Partner
23 0 23

Here is a complete breakdown of how to upload files using the Files API https://community.shopify.com/c/shopify-apis-and-sdks/full-process-for-uploading-files-to-the-files-...

Rachid_98
Shopify Partner
12 1 0

@JBraund @awwdam @mariannef  I'm having the same issue, I tried changing from IMAGE to FILE but still the post request returns bad request, I use fetch instead of axios. Would you kindly take a look at my code here:
https://community.shopify.com/c/graphql-basics-and/image-file-upload-through-graphql-api-processing-...