
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI 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:
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."
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.
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.
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);
})Create a migration script to unset references or convert them to weak references across your dataset. This is useful for one-time cleanup operations.
To make dangling references easier to spot and remove in the Studio UI, you could create a custom input component that:
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.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store