Validate array to prevent empty references in Sanity

2 replies
Last updated: Mar 10, 2023
Is it possible to make a document invalid if an array of references contains an empty reference? This is my field definition:
{
  name: 'types',
  title: 'Product type',
  description: 'You can select multiple types for compound products.',
  type: 'array',
  of: [
    defineArrayMember({
      type: 'reference',
      to: [{type: 'productType'}],
      options: {disableNew: true},
    }),
  ],
  validation: (Rule) => Rule.required().unique().error('Cannot add same product type twice'),
},
Unfortunately the validation is not working as I expect. The user can still click on "Add item" in the array, leave the reference input untouched and publish the document…
AI Update

You're running into a common issue where array validation doesn't automatically validate the individual items within the array. The required() and unique() methods on your array field only validate that the array itself exists and has unique items, but they don't prevent empty/unselected references.

To solve this, you need to add validation to the reference items themselves within the array. Here's how to fix your field definition:

{
  name: 'types',
  title: 'Product type',
  description: 'You can select multiple types for compound products.',
  type: 'array',
  of: [
    defineArrayMember({
      type: 'reference',
      to: [{type: 'productType'}],
      options: {disableNew: true},
      validation: (Rule) => Rule.required().error('Please select a product type'),
    }),
  ],
  validation: (Rule) => Rule.required().unique().error('Cannot add same product type twice'),
}

The key addition is the validation property on the defineArrayMember itself. This ensures that once a user clicks "Add item", they must actually select a reference before they can publish.

You can also add a custom validation rule on the array level to catch any empty references that might slip through:

{
  name: 'types',
  title: 'Product type',
  description: 'You can select multiple types for compound products.',
  type: 'array',
  of: [
    defineArrayMember({
      type: 'reference',
      to: [{type: 'productType'}],
      options: {disableNew: true},
      validation: (Rule) => Rule.required().error('Please select a product type'),
    }),
  ],
  validation: (Rule) => [
    Rule.required().unique().error('Cannot add same product type twice'),
    Rule.custom((value) => {
      if (value?.some(item => !item._ref)) {
        return 'All product types must be selected';
      }
      return true;
    }),
  ],
}

The custom validation checks if any array items have an empty _ref property, which would indicate an unselected reference. This provides an extra layer of protection.

For more details on validation patterns, check out the Field Validation documentation and the validation helpers guide.

Show original thread
2 replies
You should be able to use a custom validator to map over each of the product items and check if they all have a "_ref" property. You could use something like
item.hasOwnProperty('_ref')
or
"_ref" in item
to check.
https://www.sanity.io/docs/validation#091e10f957aa
Thanks User, I made it work with this info. I still believe it should be easier to mark a document as not publishable if there is a ref pointing to nothing. 🙂

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?