How to validate that a document is referenced by at least one other document?

25 replies
Last updated: Jan 28, 2026
Hi there! I have a data model with two document types, foo and bar, and bar’s can contain references to multiple foos. We want to warn if any foo exists that isn’t referenced by at least one bar, but I’m not sure how to navigate references in validation. Is there a way in the validation of foo to say “referenced by at least one bar”?
AI Update

I understand you want to validate that a foo document is referenced by at least one bar document. This is definitely possible using custom validation in Sanity, though it requires querying within your validation rule.

In your foo document schema, you can add a custom validation rule that queries the Content Lake to check if any bar documents reference the current foo. Here's how:

import { defineType } from 'sanity'

export default defineType({
  name: 'foo',
  type: 'document',
  fields: [
    // your fields here
  ],
  validation: Rule => Rule.custom(async (doc, context) => {
    const { document, getClient } = context
    const client = getClient({ apiVersion: '2024-01-01' })
    
    // Query to find any bar documents that reference this foo
    const query = `count(*[_type == "bar" && references($fooId)])`
    const count = await client.fetch(query, { fooId: document._id })
    
    if (count === 0) {
      return 'Warning: This foo is not referenced by any bar documents'
    }
    
    return true
  })
})

A few important notes:

The references() function in GROQ is perfect for this - it checks if a document contains a reference to the specified ID anywhere in its structure, which works great for your use case where bar contains references to multiple foos.

Validation context provides getClient() which gives you access to query the Content Lake. You'll need to specify an API version when getting the client.

Warning vs Error: The validation above returns a string message which shows as a validation error and blocks publishing. If you want it to be a warning instead (non-blocking), you can structure it differently:

validation: Rule => Rule.warning().custom(async (doc, context) => {
  const { document, getClient } = context
  const client = getClient({ apiVersion: '2024-01-01' })
  
  const query = `count(*[_type == "bar" && references($fooId)])`
  const count = await client.fetch(query, { fooId: document._id })
  
  if (count === 0) {
    return 'Warning: This foo is not referenced by any bar documents'
  }
  
  return true
})

Performance consideration: This validation runs a query every time the document is validated, which could impact Studio performance if you have many documents. For better performance, you might want to consider only running this check on certain events rather than on every keystroke.

The Sanity validation documentation has more details on validation rules, particularly the section on asynchronous validation using the client.

Alternatively, you could approach this from the other direction - add a custom component or dashboard widget on bar documents that shows which foo documents are orphaned, making it more of a content management workflow tool rather than a validation rule on each individual foo.

Show original thread
25 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?