stagedUploadsCreate GraphQL API creates file which can't be proccesed by fileCreate

I’m trying to upload an image. I’m using stagedUploadsCreate, which uploads the file to GCP, then I’m passing the resource URL to fileCreate, which should add the image to my store. However, I’m getting a Processing error message when checking the files page.

I tested downloading the file to my computer using the resourceURL and when opening it using GIMP I get the following message “Not a JPEG file: starts with 0x2d 0x2d”

Then I compared the original file and the downloaded file using a text editor. The files match except that the downloaded file has the following text appended to the beginning.

–05c727c6d6d7efb8678eb2a61cad52e6
Content-Disposition: form-data; name=“content_type”; filename=“content_type”

image/jpeg
–05c727c6d6d7efb8678eb2a61cad52e6
Content-Disposition: form-data; name=“acl”; filename=“acl”

private
–05c727c6d6d7efb8678eb2a61cad52e6
Content-Disposition: form-data; name=“file”; filename=“bih_0.jpeg”

Am I doing something wrong on my end?

1 Like

Hi @harispoljo :waving_hand:

The fileError.code field has quite a few errors relating to processing failures. Most often, an image will fail to process due to invalid configs during the upload step.

With the stagedUploadsCreate mutation, we need to capture the url, resourceUrl and parameters fields from the stagedTargets:

mutation StageUploadTarget($input: [StagedUploadInput!]!) {
    stagedUploadsCreate(input: $input) {
        stagedTargets {
            url
            resourceUrl
            parameters {
                name
                value
            }
        }
    }
}

{ // variables
    "input": {
        "resource": "IMAGE",
        "filename": "shopify.jpg",
        "mimeType": "image/jpeg",
        "httpMethod": "PUT"
    }
}

For the upload step, we’ll need to add parameters field to the request headers. If you’re using a client like Postman, you can use pre/post-request scripts to dynamically add the saved parameters to the header.

// post stagedUploadsCreate request
const r = pm.response.json(); // response from stagedUploadsCreate mutation
const target = r.data.stagedUploadsCreate.stagedTargets[0]

pm.collectionVariables.set("target-url", target.url);
pm.collectionVariables.set("target-params", target.parameters);
pm.collectionVariables.set(
    "target-resource-url",
    JSON.stringify(target.resourceUrl)
);;

// pre image upload request
const params = pm.collectionVariables.get("target-params");
params.forEach( p => {
    pm.request.headers.append({
        key: p.name, 
        value: p.value
    })
})

After the upload, the fileCreate mutation should consume the saved resourceUrl as the originalSource variable.

mutation fileCreate($files: [FileCreateInput!]!) {
  fileCreate(files: $files) {
    files {
      createdAt
      fileStatus
    }
  }
}

{ //variables
  "files": [{
    "contentType": "IMAGE",
    "originalSource": {{target-resource-url}}
  }]
}

Finally, we should be able to query the latest files to see the the image url:

{
    files (first:3, sortKey: CREATED_AT, reverse: true){
        nodes {
            fileStatus
            preview {
                image {
                    url
                }
            }
            fileErrors {
                code
                message
            }
        }
    }
}

Hope that helps!

1 Like

Thank you for the help!

1 Like