Computed views - Date cannot represent an invalid date-string

Hey there, I have a computed view which accepts Date parameters. When invoking it, I have the following error:
GadgetOperationError:"GGT_UNKNOWN: [GraphQL] Variable \"$startDate\" got invalid value \"2025-09-15T00:00:00.000Z\"; Expected type \"Date\". Date cannot represent an invalid date-string 2025-09-15T00:00:00.000Z.\n[GraphQL] Variable \"$endDate\" got invalid value \"2025-09-22T14:46:05.922Z\"; Expected type \"Date\". Date cannot represent an invalid date-string 2025-09-22T14:46:05.922Z."
GadgetOperationError:"GGT_UNKNOWN: [GraphQL] Variable \"$startDate\" got invalid value \"2025-09-15T00:00:00.000Z\"; Expected type \"Date\". Date cannot represent an invalid date-string 2025-09-15T00:00:00.000Z.\n[GraphQL] Variable \"$endDate\" got invalid value \"2025-09-22T14:46:05.922Z\"; Expected type \"Date\". Date cannot represent an invalid date-string 2025-09-22T14:46:05.922Z."
Any idea what's wrong?
No description
No description
15 Replies
airhorns
airhorns2w ago
i think you want DateTime, not Date there! that string is a timestamp with the hours/minutes/seconds specified which should be a DateTime ! a date is just the year/month/day but none of the rest of the bits
Yaman
YamanOP2w ago
As simple as that thanks Harry. I'm having an issue tho, my view works perfectly fine in my dev env but always timeouting in prod, even for very low dataset
view dashboardReport($currency: String, $startDate: DateTime, $endDate: DateTime) {
rewardedCreditsReport: rewardedCredits {
totalCreditRewarded: sum(amount)
totalOrdersInfluenced: count(id, where: !isNull(orderId))
totalSalesInfluenced: sum(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))
ordersAOV: avg(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where currencyCode == $currency
&& (status == "issued" || isNull(status))
&& (!isNull($startDate) ? createdAt >= $startDate : true)
&& (!isNull($endDate) ? createdAt <= $endDate : true)
]
}

redeemedCreditsReport: shopifyOrders {
totalCreditRedeemed: sum(redeemedStoreCreditAmount)
totalOrdersInfluenced: count(id)
totalSalesInfluenced: sum(cast(subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where presentmentCurrency == $currency
&& some(transactions.gateway == "shopify_store_credit" && transactions.kind != "refund")
&& (!isNull($startDate) ? shopifyCreatedAt >= $startDate : true)
&& (!isNull($endDate) ? shopifyCreatedAt <= $endDate : true)
]
}
}
view dashboardReport($currency: String, $startDate: DateTime, $endDate: DateTime) {
rewardedCreditsReport: rewardedCredits {
totalCreditRewarded: sum(amount)
totalOrdersInfluenced: count(id, where: !isNull(orderId))
totalSalesInfluenced: sum(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))
ordersAOV: avg(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where currencyCode == $currency
&& (status == "issued" || isNull(status))
&& (!isNull($startDate) ? createdAt >= $startDate : true)
&& (!isNull($endDate) ? createdAt <= $endDate : true)
]
}

redeemedCreditsReport: shopifyOrders {
totalCreditRedeemed: sum(redeemedStoreCreditAmount)
totalOrdersInfluenced: count(id)
totalSalesInfluenced: sum(cast(subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where presentmentCurrency == $currency
&& some(transactions.gateway == "shopify_store_credit" && transactions.kind != "refund")
&& (!isNull($startDate) ? shopifyCreatedAt >= $startDate : true)
&& (!isNull($endDate) ? shopifyCreatedAt <= $endDate : true)
]
}
}
Here's what it looks like, only some aggregations
airhorns
airhorns2w ago
hey @Yaman -- are you running that view in the context of one store in particular where it is timing out? the view performs well when i run it using our internal tooling so i think i must be missing something about how its running for you that makes it slow! also, what variables are you passing when it times out?
Yaman
YamanOP2w ago
Hey @[Gadget] Harry, so all stores are timing out, even the ones with small dataset Sometimes I can see successful calls but with inconsistent results (meaning that if I run the very same inline view in playground but with an explicit shopId filter in the where clause, the results might be different from when the shopId is inferred from access control context) Only the currency variable is mandatory, the date variables are optional but I see timeout with or without them
airhorns
airhorns2w ago
ok thanks for this i'll take a look!
Yaman
YamanOP2w ago
Thanks 🙏 I’m heading to bed, let me know if you need more infos, I’ll answer first time in the morning
airhorns
airhorns2w ago
ok, i fiddled with a couple things internally and the view is returning results, albeit a bit slowly now. this is definitely a bug, this view shouldn't be slow to begin with! i will discuss with the team what the deeper fix is and get back to you!
Yaman
YamanOP2w ago
Thanks Harry. While we here, are you aware of any issue with access control context? If you take a look at trace id c0f86ca40ff473f77fb5fd618476e9e8, under v2 variable, this is the result when the view is called from my app (so it should have inferred shopId filter because my models have Gelly filter access control) Now when I run an inline version of my view by explicitly setting shopId in the where clause, I got different results (and the ones I expected) Not sure what's going on or how to debug access control context Here's the inline version of my view if you want to try out:
await api.view(`
($currency: String, $startDate: DateTime, $endDate: DateTime) {
rewardedCreditsReport: rewardedCredits {
totalCreditRewarded: sum(amount)
totalOrdersInfluenced: count(id, where: !isNull(orderId))
totalSalesInfluenced: sum(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))
ordersAOV: avg(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where shopId == "11393237056"
&& currencyCode == $currency
&& (status == "issued" || isNull(status))
&& (!isNull($startDate) ? createdAt >= $startDate : true)
&& (!isNull($endDate) ? createdAt <= $endDate : true)
]
}

redeemedCreditsReport: shopifyOrders {
totalCreditRedeemed: sum(redeemedStoreCreditAmount)
totalOrdersInfluenced: count(id)
totalSalesInfluenced: sum(cast(subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where shopId == "11393237056"
&& presentmentCurrency == $currency
&& some(transactions.gateway == "shopify_store_credit" && transactions.kind != "refund")
&& (!isNull($startDate) ? shopifyCreatedAt >= $startDate : true)
&& (!isNull($endDate) ? shopifyCreatedAt <= $endDate : true)
]
}
}
`,
{
currency: "USD",
startDate: new Date("2025-09-18T00:00:00.000Z"),
endDate: new Date("2025-09-25T07:57:45.021Z")
})
await api.view(`
($currency: String, $startDate: DateTime, $endDate: DateTime) {
rewardedCreditsReport: rewardedCredits {
totalCreditRewarded: sum(amount)
totalOrdersInfluenced: count(id, where: !isNull(orderId))
totalSalesInfluenced: sum(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))
ordersAOV: avg(cast(order.subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where shopId == "11393237056"
&& currencyCode == $currency
&& (status == "issued" || isNull(status))
&& (!isNull($startDate) ? createdAt >= $startDate : true)
&& (!isNull($endDate) ? createdAt <= $endDate : true)
]
}

redeemedCreditsReport: shopifyOrders {
totalCreditRedeemed: sum(redeemedStoreCreditAmount)
totalOrdersInfluenced: count(id)
totalSalesInfluenced: sum(cast(subtotalPriceSet.presentment_money.amount, type: "Number"))

[
where shopId == "11393237056"
&& presentmentCurrency == $currency
&& some(transactions.gateway == "shopify_store_credit" && transactions.kind != "refund")
&& (!isNull($startDate) ? shopifyCreatedAt >= $startDate : true)
&& (!isNull($endDate) ? shopifyCreatedAt <= $endDate : true)
]
}
}
`,
{
currency: "USD",
startDate: new Date("2025-09-18T00:00:00.000Z"),
endDate: new Date("2025-09-25T07:57:45.021Z")
})
airhorns
airhorns2w ago
are you running the inline view in the API console? if so, it won't run with the shopify access control context
Yaman
YamanOP2w ago
No I mean, normally my view is running from my app, so this one should get the shopId filter from the access control context right? The inline view I'm running from the API console => I've explicitely set the "shopId" filter in the where clause So both should have exact same results right? But the result from frontent call is giving wrong data and the result from the API console call is giving good data Actually small detail: my frontend is calling a route which then calls the view. Maybe that's the issue? The access control context is not inherit from the route to the view?
airhorns
airhorns2w ago
ah yes that'd be it! you can do api.actsAsSession() in your route to keep that access control context alive for the view
Yaman
YamanOP2w ago
Ah nice! I knew actAsAdmin but not that one 🙏 Looks better now but I still got few timeouts. Are you still working on it or the fix you've deployed is final?
airhorns
airhorns2w ago
definitely still working on it -- there's a few different pieces here that need improvement! we're running a couple experiments to figure out exactly what to change, but im pretty sure we can make this view quite a bit faster. give me a day or two and i'll have a better idea of the timeline for when the improvements will ship!
Yaman
YamanOP7d ago
Hey @[Gadget] Harry, quick question: these 2 views are the exact same on paper but the first one always timeouting vs the second run smoothly. Is this part of the bug you're working on or is there any performance advantages to use a global where clause versus aggregation method where parameter?
No description
airhorns
airhorns7d ago
yes indeed, the where conditions at the top level should be preferred to the where conditions within the aggregate functions. the top level ones allow for much more performant query plans, whereas the ones within the function work in such a way that they can work with sibling calls to similar functions with different queries

Did you find this page helpful?