I am performing a Bulk Operation for Orders, Customers and AbandonedCheckouts that have been updated within a date range.
The bulker operation query works fine and I can download the JSONL files.
The date range query filter works fine for the Customers and Orders, but not for the AbandonedCheckouts. I get records returned for Customers and Orders, but 0 records returned for AbandonedCheckouts when I know records exist during that timeframe as I have tested getting all the records and can see them.
My GraphQL Query (in Dotnet C#) for AbandonedCheckouts inside the bulk operation query is:
abandonedCheckouts(query:\"updated_at:>=" + fromDT + " AND updated_at:<" + toDT + "\") { edges { node { id billingAddress { city country countryCodeV2 province provinceCode zip } completedAt createdAt customer { id firstName email } updatedAt totalPriceSet { shopMoney { amount currencyCode } } } } }
which returns 0 records regardless of the DateTime variable values for fromDT and toDT.
If I change the filter to first or last it returns ALL of the AbandonedCheckouts for the shop, not just first x or last x.
As I mentioned, this exact same filter and query structure works for Customers and Orders so Iâm wonderiing if there is something different about AbandonedCheckouts that I am missing?
If you test your query outside of the bulk operations does it work? I would recommend testing that and adding in the syntax debugging headers to get a clear view of how itâs being parsed.
Thanks @KyleG-Shopify . Iâm not sure how to add that header using ShopifySharp.GraphQL but Iâm getting the following responses for the following queries outside the bulk operation:
abandonedCheckouts(first: 10) { edges { node { id billingAddress { city country countryCodeV2 province provinceCode zip } completedAt createdAt customer { id firstName email } updatedAt totalPriceSet { shopMoney { amount currencyCode } } } } }
Response: syntax error, unexpected IDENTIFIER (âabandonedCheckoutsâ) at [1, 1]
query AbandonedCheckouts { abandonedCheckouts(first: 10) { edges { node { id billingAddress { city country countryCodeV2 province provinceCode zip } completedAt createdAt customer { id firstName email } updatedAt totalPriceSet { shopMoney { amount currencyCode } } } } } }
Response: It gives me the first 10 as expected
NOTE: If I try to do this query (2) in the bulk operation it fails with
Graph user errors were returned: System.Collections.Generic.List1[System.String]: Invalid bulk query: Field 'query' doesn't exist on type 'QueryRoot' System.Collections.Generic.List1[System.String]: Invalid bulk query: Field âAbandonedCheckoutsâ doesnât exist on type âQueryRootâ
but query (1) works but it returns ALL historical AbandonedCheckouts not just the first 10. Seems like either the filter should work or it should allow the additional âquery AbandonedCheckouts {â in the bulk operation.
Noting also that for Orders and Customers the filter works fine in the format of (1) above.
query AbandonedCheckouts { abandonedCheckouts(query:"updated_at:>=" + fromDT + " AND updated_at:<" + toDT + "") { edges { node { id billingAddress { city country countryCodeV2 province provinceCode zip } completedAt createdAt customer { id firstName email } updatedAt totalPriceSet { shopMoney { amount currencyCode } } } } } }
Response: Graph errors were returned: you must provide one of first or last
query AbandonedCheckouts { abandonedCheckouts(first: 10, query:"updated_at:>=" + fromDT + " AND updated_at:<" + toDT + "") { edges { node { id billingAddress { city country countryCodeV2 province provinceCode zip } completedAt createdAt customer { id firstName email } updatedAt totalPriceSet { shopMoney { amount currencyCode } } } } } }
Response: ValueKind = Object : â{âdataâ:{âabandonedCheckoutsâ:{âedgesâ:[]}},âextensionsâ:{âcostâ:{ârequestedQueryCostâ:14,âactualQueryCostâ:2,âthrottleStatusâ:{âmaximumAvailableâ:2000.0,âcurrentlyAvailableâ:1998,ârestoreRateâ:100.0}},âsearchâ:[{âpathâ:[âabandonedCheckoutsâ],âqueryâ:âupdated_at:>=01/05/2025 00:00:00 AND updated_at:<31/05/2025 00:00:00â,âparsedâ:{âandâ:[{âfieldâ:âupdated_atâ,ârange_gteâ:â2025-05-01T00:00:00+00:00â,ârange_ltâ:â2025-05-31T00:00:00+00:00â},{âfieldâ:âdefaultâ,âmatch_allâ:â00â},{âfieldâ:â00â,âmatch_allâ:â00â}]},âwarningsâ:[{âfieldâ:â00â,âmessageâ:âInvalid search field for this query.â}]}]}}â
NOTE: AbandonedCheckouts docs shows updated_at as a valid query field.
I canât see any difference in the documentation between AbandonedCheckouts and Customers and Iâm using the same query syntaxand filter fields but getting different results.
Iâm also finding that using updated_at filter on Customers doesnât seem to return the correct records in both the bulk query and the normal query.
customers(query:"updated_at:>=" + fromDT + " AND updated_at:<" + toDT + "") { edges { node { id amountSpent { amount currencyCode } createdAt defaultAddress { city country countryCodeV2 province provinceCode zip } email firstName lastOrder { id createdAt } numberOfOrders updatedAt verifiedEmail } } }
in the bulk operation returns 3 records.
query CustomerList { customers(last: 200) { edges { node { id amountSpent { amount currencyCode } createdAt defaultAddress { city country countryCodeV2 province provinceCode zip } email firstName lastOrder { id createdAt } numberOfOrders updatedAt verifiedEmail } } } }
not in the bulk operation returns the same 3 records.
However, I ran a bulk operation whcih downloaded ALL Customers for the shop and looking at the records I can see 413 records in the JSONL file that have an updatedAt property in May 2025 which is the range in the query with fromDT=01/05/2025 and toDT=30/05/2025.
Most of these 413 customers were CreatedAt in that time too which is why I know the 3 is wrong because that would mean only 3 new/updated customer in the whole month which is just wrong.
I canât use CreatedAt because I need to make sure we have the updated data for each record which is why we are using UpdatedAt.
I figured out it is to do with the DateTime string format when converting from DateTime implicitly. Excplictly setting the format works as expected e.g.
string fromDT = new DateTime(2025, 5, 1).ToString(âyyyy-MM-ddT00:00:00Zâ);
string fromDT = new DateTime(2025, 5, 1).ToString(âyyyy-MM-ddâ);
Such a duh moment for me⌠Should have been more obvious to me considering Iâm passing strings to the GrahQL service that the exact format needs to be specified rather than expecting C# to use the correct format when implicitly converting to a string.
Hopefully this helps someone else getting stuck on the same thing.
I can see now in this error message that it is parsing the date properly but then using the additional 00 after the : chars as query fields: ValueKind = Object : â{âdataâ:{âabandonedCheckoutsâ:{âedgesâ:[]}},âextensionsâ:{âcostâ:{ârequestedQueryCostâ:14,âactualQueryCostâ:2,âthrottleStatusâ:{âmaximumAvailableâ:2000.0,âcurrentlyAvailableâ:1998,ârestoreRateâ:100.0}},âsearchâ:[{âpathâ:[âabandonedCheckoutsâ],âqueryâ:âupdated_at:>=01/05/2025 00:00:00 AND updated_at:<31/05/2025 00:00:00â,âparsedâ:{âandâ:[{âfieldâ:âupdated_atâ,ârange_gteâ:â2025-05-01T00:00:00+00:00â,ârange_ltâ:â2025-05-31T00:00:00+00:00â},{âfieldâ:âdefaultâ,âmatch_allâ:â00â},{âfieldâ:â00â,âmatch_allâ:â00â}]},âwarningsâ:[{âfieldâ:â00â,âmessageâ:âInvalid search field for this query.â}]}]}}â
So it is the T missing from the implicit conversion, instead having a whitespace between Date and Time components which indicates to the GraphQL that the next characters are new fields in the query.