Make the server reject a stale base version

Send a version token with the mutation. HTTP supplies one standard mechanism: an entity tag from the read can be returned in an If-Match precondition. Under RFC 9110, a server must not perform the requested method when the supplied tag does not match the current representation; the normal response is 412 Precondition Failed.

That prevents a lost update only when the service actually evaluates the precondition for the state-changing request. Comparing versions in browser code is not equivalent because another change can occur after the comparison.

Explain what changed without destroying either value

After a conflict, keep:

  • the local draft the operator attempted to save;
  • the base version it was edited from;
  • the current server version and its known author or time; and
  • the current permission state.

Offer concrete choices. “Compare” exposes the values side by side. “Copy my draft” provides an escape hatch. “Reload current” deliberately replaces the field only after warning that the local draft will leave the editor. “Review and retry” starts from the current version, lets the operator merge the intended change, and sends a new precondition.

Do not label a blind overwrite “retry.” If the operator lost permission, retain or copy the draft but remove the save path. Version validity and authorization are separate server checks.

Give the error a name and a correction path

The W3C's error-identification guidance requires an error to be identified in text. Say that the record changed before save; do not rely only on a red border. When the conflict appears without moving focus, apply its status-message guidance so the full message is programmatically determinable.

Acceptance checks

  • Every editable read carries a server-recognized version identifier.
  • A stale precondition cannot perform the write.
  • The error names the record and says that a newer version exists.
  • The local draft remains available until the operator chooses.
  • Compare distinguishes base, current, and local values.
  • Reload warns before replacing the local editor value.
  • Retry uses the current version and rechecks authorization.
  • Permission loss offers copy or exit, not an unauthorized save.

This contract does not choose a merge algorithm or transaction model. It makes the conflict visible and keeps the service responsible for preventing overwrite.