# Concurrent edits converge reliably

**Version:** v2.18.0

**Published:** July 20, 2026

This release hardens the document store's sync engine with four fixes found through two-client concurrency testing. There are no API changes and nothing to migrate. If several people edit the same documents through your app, upgrade. These fixes build on the patch channel introduced in v2.17.0 and apply to both `@sanity/sdk` and `@sanity/sdk-react`. If your app uses the Portable Text Editor, also update [@portabletext/plugin-sdk-value](https://www.npmjs.com/package/@portabletext/plugin-sdk-value) to 7.1.0

## Documents converge after unexpected remote changes

When a remote transaction didn't match the store's optimistic prediction, publishing from another client for example, the store could advance its server snapshot while the local view kept stale values until the next edit. The store now recomputes the local view from the new server snapshot plus any still-pending local edits, so every client settles on the same document.

## Reconnects replay cleanly

The shared listener now resumes after a dropped connection instead of starting over. Replayed events are recognized and discarded rather than applied twice, events are ordered by revision so a replay can't leave a document out of sync, and events belonging to one transaction that spans several documents (a publish, for instance) are grouped and applied together.

## Increments accumulate instead of colliding

`inc` and `dec` patches passed to `editDocument()` previously collapsed into plain `set` operations before reaching the server, so concurrent increments overwrote each other. They now keep their operational form end to end. Two clients that both read a count of 11 and increment it now land on 13, not 12.

## No more phantom array items

A `set` targeting a keyed array path that no longer exists, such as patching a span another client just deleted, used to fabricate a minimal object at that path. The server ignores such patches, so the local document diverged from server truth, and collaborative editors like Portable Text could crash on the malformed node. The local applier now matches server behavior: if the keyed path doesn't resolve, the operation is a no-op.

## Dataset permission checks no longer send cookies

The request that fetches dataset permissions no longer includes browser credentials. Token-authenticated apps no longer need credentialed CORS configured for that request.

## Local development iframe fallback

Falls back to the iframe title during local development when the app runs embedded in the dashboard.

