Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

createProductMedia results in "Media failed to process because the image could not be processed"

createProductMedia results in "Media failed to process because the image could not be processed"

Viglucci
Shopify Partner
3 0 1

I am following a number of resources on the Shopify documentation website and blog around using the `stagedUploadsCreate` mutation to create a staged URL, however, once I try and use the staged resource URL in a later `productCreateMedia` mutation, the image is not attached to the product.

 

Docs: https://shopify.dev/api/examples/product-media


I suspect that there may be an issue with the S3 object being uploaded as private. If I manually try to visit the S3 object URL represented by `resourceUrl`, I receive an "access denied" response. I suspect that this may be resulting in the Shopify backend being unable to request the file during the `productCreateMedia` mutation as well. The strange thing is that `productCreateMedia` does not return any errors, the errors only show on the Shopify admin dashboard. Example below.

 

Screenshot_1.png

Is the URL given to `productCreateMedia` supposed to be a signed S3 object URL? If so, how would you produce such a URL?

I did notice that when using `PUT` for the `httpMethod` for `stagedUploadsCreate`, the uploadUrl seems to come back as signed or with additional query params, however when using `POST` that is not the case.

Example Code (stagedUploadsCreate)

 

 

const input = [
  {
    fileSize: file.size.toString(),
    filename: file.originalname,
    httpMethod: "POST",
    mimeType: file.mimetype,
    resource: "IMAGE",
  }
];

const {body} = await client.query({
  data: {
    query: `
      mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
        stagedUploadsCreate(input: $input) {
          stagedTargets {
            resourceUrl
            url
            parameters {
              name
              value
            }
          }
          userErrors {
            field
            message
          }
        }
      }
    `,
    variables: {
      input
    }
  }
});

 

 

 

Example Code (upload):

 

 

import fetch, {FormData} from 'node-fetch'

const formData = new FormData();

parameters.forEach(({name: paramName, value}) => {
  formData.append(paramName, value)
});
formData.append('file', file.buffer, {
  contentType: file.mimetype,
  filename: file.originalname
});

const response = await fetch(uploadUrl, {
  method: 'POST',
  body: formData
});

 

 

 

Example Code (productCreateMedia):

 

 

const variables = {
  id: productId,
  media: [
    {
      originalSource: resourceUrl,
      mediaContentType: "IMAGE"
    }
  ]
};

const {body} = await client.query({
  data: {
    query: `
        mutation createProductMedia(
          $id: ID!
          $media: [CreateMediaInput!]!
        ) {
          productCreateMedia(productId: $id, media: $media) {
            media {
              mediaContentType
              preview {
                image {
                  id
                }
              }
              mediaErrors {
                code
                details
                message
              }
              mediaWarnings {
                code
                message
              }
            }
            product {
              id
            }
            mediaUserErrors {
              code
              field
              message
            }
          }
        }
    `,
    variables
  }
});

 

 

Reply 1 (1)

Viglucci
Shopify Partner
3 0 1

I ultimately found the solution by reading this post: https://community.shopify.com/c/shopify-apis-and-sdks/full-process-for-uploading-files-to-the-files-...

My issue was that I was not passing the required headers for the request to upload the file to the AWS staging URL. Once I add the headers from `formData.getHeaders()`, the Shopify backend was then able to retrieve the image data and upload it to my product.