Creating Draft Order - Email is invalid

When trying to create a draft order through the Graph QL API I am getting the error returned as;

{
    "draftOrderCreate": {
        "draftOrder": null,
        "userErrors": [
            {
                "field": [
                    "email"
                ],
                "message": "Email is invalid",
                "__typename": "UserError"
            }
        ],
        "__typename": "DraftOrderCreatePayload"
    }
}

The odd thing is this is a customer that already exists on the store - and has placed orders in the past.

In the create payload I am sending both the Customer ID in the purchasingEntity field as well as the email in the “email” field.

Also, strangely, the draft order can be created through the Admin interface no problem.

The email looks inconspicuous and is a normal “@gmail.com” email. I can see in the timeline of the customer that emails have been sending normally.

I tried just sending the customerId in purchasingEntity and not including the email and that actually seemed to work fine - so there is a work around, but still strange.

Can you omit the purchasingEntity and just try passing email?

Hey @ozzyonfire,

I tested this on my test shop and couldn’t reproduce the “Email is invalid” error. Passing both customerId and email together worked fine across multiple scenarios.

Your current implementation (customerId-only) is working so you’re good to move forward with that, but if you’d like to investigate further so we can understand what’s causing the validation error in your environment, I’m happy to help dig into it.

A few things that could help narrow this down:

  • Which API version are you using?
  • Can you share the x-request-id from a failed request?
  • Are there other fields in your mutation beyond customerId and email that might be contributing?

Hi @KyleG-Shopify thanks for the info and sorry for the delayed response. I didn’t see the issue for a couple of days and I assumed that the issue was resolved.

However, it’s back and I have a little more info.

During draft order creation, the client is passing in another inconspicuous gmail account - different from the first time. (And they usually get one or two emails per upload that give them problems). I am able to reproduce this on my dev store, so I can share request ids.

Steps are:

  1. Draft order is created with just an email and some line items. This operation fails with a user error message.
{
    "field": [
        "email"
    ],
    "message": "Email is invalid",
    "__typename": "UserError"
}

X-Request-ID: 25aa0690-a1f0-4fc4-9edc-1b3cd1bf101e-1763737735

  1. Even though the draft order fails, it actually creates the customer in the shop, silently - I am not sending a request to do this. And the customer shows up with information that was on the order. I.e. first name, last name, default address and email address.
  2. If we try to create another draft order that contains the email field, the draft order fails with the same error. However, if we omit the email field and use the purchasingEntity.customerId field instead, the order is created successfully. If both the email and purchasingEntity fields are used, it fails.

Failed X-Request-ID: e8cf0849-c539-4f9a-ada2-810687ba55b2-1763738283
Successfull X-Request-ID: fc3b3d1c-9958-4e61-aa15-e52c468bd275-1763738388

Using API Version 2025-07

Hopefully that helps. Please let me know what you find out.

Thanks for sharing that. I was able to find this in our logs, but the specific reason for the userError in the validation isn’t completely clear to me. The error does suggest there’s something with the format that’s causing the validation to fail.

I was able to replicate the exact error though. For me, this was happening with a hidden unicode character in the email address. Visibly everything looked ok, but that character was breaking the validation.

Are you able to check if something like this may have been sent in those requests? Do you have anything within your app to clean up email addresses before sending in cases where there may be a hidden value?

As you mentioned, using just customerId (without the email field) should continue to work as a workaround while we investigate the source of the issue.

Okay interesting you mention this. The first time the customer reached out, they sent me a .csv file of the email addresses that contained Chinese characters when I viewed it on my end.

However, these new email addresses look okay - and I can view them in plaintext and everything seems fine.

I will do some more investigation on this and try to actually write out the email in a clean .csv file and see how that works. Right now, I just parse the value and pass it along, so I may try sanitizing the email beforehand… I’ll follow up with what I find out.

Thanks for the support on this!

1 Like