Resolving a query issue with Sanity's GROQ parsers

2 replies
Last updated: Jun 12, 2024
*[_type=="trendingPage"][0]{
  nodes[]->{
    ...,
    prices[] | order(period asc) {
      period,
      "id": _key
    }
  }
}
Hi, this should be a valid query right? I get the value I am expecting when I do this but when I try to generate types for this query, I get the error, "Cannot determine property key for type: PipeFuncCall" and sanity typegen do not generate the type of the query.
Am I doing something wrong?
AI Update

This looks like a known limitation with Sanity TypeGen when dealing with pipe functions inside projections. Your query is valid GROQ and works correctly, but the TypeGen parser is having trouble analyzing the structure when you use a pipe operator (|) with functions like order() inside an array projection.

The issue is specifically with this part of your query:

prices[] | order(period asc) {
  period,
  "id": _key
}

TypeGen struggles to determine the property key when you're combining:

  1. An array projection (prices[])
  2. A pipe operator (|)
  3. A function call (order())
  4. Another projection with field selection

Workarounds you can try:

Option 1: Wrap with defineQuery but manually type the result

If you're using defineQuery, you can manually type the result instead of relying on automatic generation:

import { defineQuery } from 'next-sanity'
import type { TrendingPage } from './sanity.types'

const TRENDING_QUERY = defineQuery(`
  *[_type=="trendingPage"][0]{
    nodes[]->{
      ...,
      prices[] | order(period asc) {
        period,
        "id": _key
      }
    }
  }
`)

// Manually type the result
type TrendingQueryResult = TrendingPage & {
  nodes: Array<{
    prices: Array<{
      period: string;
      id: string;
    }>;
  }>;
}

Option 2: Simplify the projection structure

Try moving the order() outside the projection or restructuring the query:

*[_type=="trendingPage"][0]{
  nodes[]->{
    ...,
    "prices": prices[] {
      period,
      "id": _key
    } | order(period asc)
  }
}

Option 3: Use client-side sorting

If the above doesn't work with TypeGen, you could sort the prices array in your application code after fetching, which would allow TypeGen to properly analyze the simpler query structure without the pipe function.

This is a limitation of the experimental TypeGen feature - it doesn't yet support all valid GROQ syntax patterns, particularly complex combinations of pipe operators and projections. The GROQ query itself is perfectly valid according to the GROQ pipeline components specification, but the static analysis tool has trouble parsing it. You might want to check the Sanity GitHub repository to see if there's an existing issue for this, or consider filing one if it's not already reported.

Hi!
That looks like a discrepancy between our different groq parsers.



*[_type=="trendingPage"][0]{
  nodes[]->{
    ...,
    "prices": prices[] | order(period asc) {
      period,
      "id": _key
    }
  }
}

Should work and yield the same result
THANK YOU!It works! You helped me a lot on this, really appreciate it.

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.

Was this answer helpful?