Joint session with Vercel: How to build intelligent storefronts (May 15th)

it looks like our problems are caused by editors publishing drafts after backend token has updated docs, and thus overwriting it

20 repliesLast updated: Nov 29, 2025

Hi, we have a problem with drafts. By using the history api trying to make sense of that happens, it looks like our problems are caused by editors publishing drafts after backend token has updated docs, and thus overwriting it. Here’s what I think is going on:1. An editor starts editing a document, could be by accident, and then forgets to publish it.
2. Our server updates the document one or more times
3. Some editor that comes across the doc, publishes the draft.
It looks like this process
causes us to loose all the patches from step 2. And the time from 1-3 may be a few seconds (not likely for anything to happen at step 2), or days (more likely that our server did some work at step 2).
• I could encourage all editors to discard all drafts that they come across, and don’t publish anything that they haven’t edited the last few seconds.
This should keep the changes from step 2, right?• If editors are encouraged to keep drafts open only for a short period of time before publishing, the probability of something else being written to the doc in the meantime is very low. However, there’s still a small chance that step 2 will happen even though an editor is working with the doc only for a second or two, before publishing.
So what’s how do we prevent editors from overwriting updates our backend did?
AI Update

You've correctly identified the classic race condition problem with drafts overwriting backend updates. The good news is Sanity provides a robust solution through optimistic concurrency control using the ifRevisionID parameter.

The Core Solution: Use ifRevisionID for Backend Mutations

When your backend updates documents, you should use the ifRevisionID parameter in your patch mutations. This prevents the exact scenario you're describing:

// In your backend code
await client
  .patch(documentId)
  .ifRevisionID(currentRevisionId) // Only apply if this revision matches
  .set({ yourField: newValue })
  .commit()

If the revision ID doesn't match (because a draft exists or someone else modified it), the mutation will fail with a 409 Conflict status, allowing you to:

Why This Happens

The issue stems from Sanity's draft system:

Additional Strategies

For your backend:

For your editors (workflow improvements):

Alternative architecture: If your backend updates are frequent and critical, consider whether editors should be modifying those fields at all. You might:

Example: Detecting Conflicts

// Backend mutation with conflict handling
try {
  const doc = await client.getDocument(docId)
  await client
    .patch(docId)
    .ifRevisionID(doc._rev)
    .set({ backendField: value })
    .commit()
} catch (error) {
  if (error.statusCode === 409) {
    // Conflict detected - draft exists or doc changed
    console.log('Conflict: document was modified')
    // Handle: retry, merge, or alert
  }
}

The ifRevisionID approach is exactly what the Transactions documentation recommends for preventing lost updates in read-write cycles. It's Sanity's built-in solution for optimistic locking and will catch both draft conflicts and concurrent modifications.

Show original thread
20 replies

Was this answer helpful?

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.

Related contributions