How to auto-remove references when deleting referenced documents in Sanity
I understand you're dealing with dangling references - when you delete a document in Sanity, other documents that reference it are left with broken/orphaned references that just hang there pointing to nothing. This is indeed frustrating!
Unfortunately, Sanity doesn't have a built-in automatic cascade delete feature to remove references when the referenced document is deleted. This is by design - Sanity protects referential integrity by preventing you from deleting documents that are referenced elsewhere.
However, you have several approaches to handle this:
Understanding the Protection
As mentioned in this community discussion, Sanity will block deletion attempts when documents have incoming references. You'll get an error like "You are trying to delete a document which is referenced by X other documents."
Solutions
1. Use Weak References (Preventative)
If you know certain references should be deletable without blocking, use weak references in your schema:
{
name: 'relatedDocument',
type: 'reference',
to: [{type: 'someType'}],
weak: true // This allows the referenced doc to be deleted
}When creating references via mutations, use _weak: true:
{
_type: 'reference',
_ref: 'document-id',
_weak: true
}Weak references are perfect for situations where you want references that won't prevent deletion - they're essentially "soft links" that can point to non-existent documents without causing validation errors.
2. Clean Up Existing References with Sanity Functions (Recommended)
Use Sanity Functions to automatically clean up dangling references when documents are deleted. This is the modern, recommended approach for handling this kind of automation:
// In your sanity.blueprint.ts
export default {
functions: [{
name: 'cleanup-references',
trigger: 'document.delete',
handler: async ({ event, client }) => {
const deletedId = event.documentId;
// Find docs referencing the deleted doc
const referencingDocs = await client.fetch(
`*[references($id)]{ _id, _rev, ... }`,
{ id: deletedId }
);
// Create patches to remove the references
// Implementation depends on your schema structure
}
}]
}Sanity Functions run serverless on Sanity's infrastructure and are ideal for this use case - they trigger automatically on document events without requiring external hosting.
3. Find and Remove References Manually
Query for documents without incoming references before deleting:
*[_type == "yourType" && count(*[references(^._id)]) == 0]Or find which documents are blocking deletion:
client.fetch('*[references($id)]._id', { id: 'document-to-delete' })
.then((results) => {
console.log('These documents reference this:', results);
})4. Migration Script for Cleanup
Create a migration script to unset references or convert them to weak references across your dataset. This is useful for one-time cleanup operations.
Making References Removable in the Editor
To make dangling references easier to spot and remove in the Studio UI, you could create a custom input component that:
- Detects broken references (where the referenced document no longer exists)
- Provides a visual indicator
- Offers a "Remove broken reference" button
The most sustainable long-term approach is combining weak references (where appropriate in your schema) with Sanity Functions to handle cleanup automatically. This gives you the "remove broken links automatically" behavior you're looking for without manual intervention - similar to how Obsidian's dangling links plugins work, but built into your content operations.
Show original thread2 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.