ClientError: Subscript ranges must have integer endpoints in Sanity

7 replies
Last updated: Nov 11, 2020
Hey I'm suddenly getting an error on my sapper/sanity build and can't find an explanation online, any ideas?
ClientError: Subscript ranges must have integer endpoints
    at onResponse (C:\Users\...\web\node_modules\@sanity\client\lib\http\request.js:27:13)

AI Update

This error is happening because GROQ has restrictions on what can be used in array subscript ranges. Based on a GitHub issue from the Sanity team, this is actually intentional behavior in Sanity's GROQ implementation, even though it works differently in groq.dev.

The error "Subscript ranges must have integer endpoints" occurs when you try to use document fields or expressions as endpoints in array slicing operations. According to the GROQ syntax documentation:

Due to parser ambiguity with filters, the following access operators can only take literals, not arbitrary expressions: array element access (e.g. array[0]), array slices (e.g. array[1..3]), and object attribute access (e.g. object["attribute"]).

This means you can't do things like:

  • array[0...postCount]
  • array[0...^.postCount]
  • array[0...@.postCount]

You can only use literal numbers:

  • array[0...5]
  • array[1..3]

Why does groq.dev work differently? The JavaScript implementation of GROQ (used by groq.dev) predates this design decision and accepts expressions. However, Sanity's production API enforces the stricter syntax to avoid parser ambiguity.

Workarounds:

  1. Use literal values: If you know the count, hardcode it: *[_type == "post"][0...3]
  2. Filter after fetching: Fetch all items and handle limiting in your frontend code
  3. Restructure your query: Instead of dynamic slicing, use filters to achieve similar results

If you're suddenly seeing this error after it was working, you may have:

  • Updated your @sanity/client version (newer versions are stricter)
  • Changed from using groq.dev to actual API calls
  • Modified your query to use dynamic values in slices

The Sanity team mentioned this could potentially be revisited in the future, but for now it's a deliberate limitation. Check all your GROQ queries for array slicing operations ([n..m] or [n...m]) and make sure they only use literal integer values, not variables or field references.

Show original thread
7 replies
Hey there! Seems like a parser error - could you share the relevant query if possible? Are you using any subscript ranges like
anything[2..5]
in your query?
export function preload({ params, query }) {
        const numBooks = 12;
        const p = parseInt(query.p)
        const bookStart = p ? (p - 1) * numBooks : 0;
        const sort = query.sort ? query.sort : 'order(title asc)';
        const bookEnd = (p) * numBooks
        const bookSplice = '[' + bookStart + '...' + bookEnd + ']'
        const filter = 
{
            'bookCount': count(*[_type == 'book' 
                                    && defined(slug.current) 
                                    && !(_id in path("drafts.**"))
                                    && defaultBookVariant.price > 0
                                ]),
            'books': *[_type == 'book' 
                        && defined(slug.current) 
                        && !(_id in path("drafts.**"))
                        && defaultBookVariant.price > 0
                        ] {
                            ...,
                            "images": defaultBookVariant.images[0].asset->url,
                            authors[]->{name, slug},
                            "price": defaultBookVariant.price,
                            "binding": defaultBookVariant.binding,
                            ...}
                            | 
 + sort + bookSplice +                            
}
        return client
        .fetch(filter)
        .then(res => {
                const {bookCount , books} = res
                return { bookCount, books };
        }).catch(err => this.error(500, err));
Hey there! Seems like a parser error - could you share the relevant query if possible? Are you using any subscript ranges like
anything[2..5]
in your query?
this code is unchanged from working earlier this week though
Ok, that was a helpful direction. It seems like my code doesn't default properly and it puts undefined in the range
Sounds like you found the culprit! 🚀
Indeed! Thanks for the clue!

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?