Skip to content

Concurrent Edits

Arun Prakash edited this page Nov 3, 2026 · 1 revision

Concurrent Edits

Two people (or two devices) load the same post, both edit it, both save: the second save silently overwrites the first. updateIfUnmodified refuses the save when the item changed on the server after you loaded it.

final post = (await client.posts.retrieve(RetrievePostRequest(id: 42, context: RequestContext.edit))).dataOrThrow();

// ... the user edits ...

final r = await client.posts.updateIfUnmodified(
  UpdatePostRequest(id: post.id, title: 'Renamed'),
  lastModifiedGmt: post.modifiedGmt!,
);

if (r case WordpressFailureResponse(:final error?) when error.code == UpdateOperation.conflictErrorCode) {
  // someone saved it since you loaded it: reload, merge, ask the user
} else if (r.isSuccessful) {
  // saved
}

It is available on every built-in interface with an update operation (posts, pages, media, navigations, ...). client.resource<T> has plain update only.

How it works

  1. A small GET for the item with _fields=modified_gmt&context=edit. It bypasses CacheMiddleware, so a cached copy never hides a newer save.
  2. If its modified_gmt differs from lastModifiedGmt, nothing is sent and a failure is returned.
  3. Otherwise the normal update is sent.
Failure Status error.code
Changed on the server 409 UpdateOperation.conflictErrorCode (wp_client_conflict)
The item has no modified_gmt 412 UpdateOperation.noModifiedErrorCode (wp_client_no_modified_gmt)
The check itself failed (offline, 404, 401, ...) that response's that response's

Limits

  • WordPress has no conditional update, so a save that lands between the check and the update is not detected. The window is one round trip.
  • Only resources with modified_gmt can be checked: posts, pages, media and navigations. Terms, users, comments and templates fail with noModifiedErrorCode; use update for those.
  • Pass the modifiedGmt of the copy the user edited, not of a later reload.
  • modified_gmt has one second resolution.

Clone this wiki locally