Reference dereferencing fails after order() in array projection
I can see why this is confusing! The issue you're running into is related to how GROQ evaluates the scope when you combine array slicing with projections that include reference dereferencing.
When you write:
'dominantTerpenes': terpenes|order(percent desc)[0..2]{
percent,
mg,
'name': terpene->name
}The problem is that the chained operations without explicit separators can cause GROQ to lose the proper context for the terpene->name reference lookup. When you slice the array with [0..2] and immediately follow it with a projection {...}, the reference resolution isn't working as expected.
The fix is to add explicit pipe operators between your operations:
'dominantTerpenes': terpenes | order(percent desc) | [0..2] | {
percent,
mg,
'name': terpene->name
}According to the pipeline components documentation, projections can optionally use the pipe operator for separation from other components. By explicitly piping between operations, you're making the data flow clear: take terpenes → order it → slice it → project it with dereferencing.
Why does the first query work but not the second?
In your first example, the projection happens directly on the original terpenes array without any intermediate operations, so the reference context is straightforward. When you add ordering and slicing, the way the operations chain together affects how GROQ evaluates the scope for each object during projection.
Alternative approach:
You could also project first (including the dereference), then order and slice:
'dominantTerpenes': terpenes[]{
percent,
mg,
'name': terpene->name
} | order(percent desc)[0..2]This works because you're resolving all the references before doing any ordering or slicing operations, so there's no ambiguity about the evaluation context.
Both solutions should resolve your empty array issue. The key takeaway is that when combining reference dereferencing with array operations like ordering and slicing, being explicit with pipe operators helps GROQ maintain the proper evaluation scope throughout the pipeline.
Show original thread12 replies
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.