Are there some limitations on -> when nested like this?

13 replies
Last updated: Jan 28, 2026
OK, so I have a document that contains an array objects, and each object have a reference to another document. GROQ, exemplified with books:

*[_type == "collection"] {

"title": collection_title,

"books": collection_books[]{

"title": collection_book->book_title,

"persons": collection_book->persons[]{

"type": type,

"firstname": person->firstname

}

}

}

Problem here is that
person->firstname
doesn't return anything. If I just write
person
then _ref and _type is returned as expected, but -> doesn't seem to work. Are there some limitations on -> when nested like this?
AI Update

Looking at your query, person->firstname should actually work fine in GROQ - there are no inherent limitations on nested dereferencing. The -> operator works in nested contexts, so the issue is likely something else.

Here's what's probably happening:

Most likely issue: Field naming

Check if the field on the referenced person document is actually called firstname. It might be:

  • firstName (camelCase)
  • first_name (snake_case)
  • name (different field entirely)

When you write person and see {_ref: "...", _type: "reference"}, that confirms the reference exists. But if person->firstname returns nothing, the referenced document probably doesn't have a firstname field.

Solution: Use a projection to see what fields exist

Try this to inspect what's actually in the referenced person document:

*[_type == "collection"] {
  "title": collection_title,
  "books": collection_books[]{
    "title": collection_book->book_title,
    "persons": collection_book->persons[]{
      "type": type,
      "personData": person->
    }
  }
}

This will return the entire referenced person document, showing you what fields are actually available.

Once you know the correct field name:

*[_type == "collection"] {
  "title": collection_title,
  "books": collection_books[]{
    "title": collection_book->book_title,
    "persons": collection_book->persons[]{
      "type": type,
      "firstname": person->firstName  // or whatever the actual field name is
    }
  }
}

Alternative: Use explicit projection syntax

If direct field access still doesn't work (which would be unusual), you can use projection syntax:

"persons": collection_book->persons[]{
  type,
  "firstname": person->{firstname}.firstname
}

Or to get multiple fields from the person:

"persons": collection_book->persons[]{
  type,
  "personInfo": person->{
    firstname,
    lastname,
    email
  }
}

The nested -> operator works fine in GROQ as described in Sanity's projections documentation, so this is almost certainly a field naming issue. Check your actual document structure to confirm the field name.

Show original thread
13 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.

Was this answer helpful?