Records stale or duplicated
A record view is a business projection at one moment. It can become stale or duplicated through async updates, pagination, filtering, unstable ids, or double-mounted components. Do not patch by position or display text; fix ids and snapshot lifetime.
Common causes
| Cause | Symptom |
|---|---|
| Unstable record id | Sorting makes an action target the wrong row |
| Array index used as key | Deletion reuses old component state |
| Double mount | A record appears twice or an action executes twice |
| Async race | An old response overwrites newer records |
| Stale snapshot | Agent uses a deleted or updated record |
| Pagination / virtual list | Agent sees a window but assumes the whole set |
| Multiple tabs | Two pages maintain different state |
Principles
- Derive record ids from business keys, not array positions.
- Recheck the target record before execution; the protocol validates folded record ids.
- Refresh descriptions after navigation, filtering, sorting, pagination, or writes.
- Give each record one projection owner to avoid duplicate registration.
- Expose totals and windows explicitly; never truncate silently.
- Version or cancel async responses so an old response cannot overwrite a newer state.
Duplicate execution
If one user action creates two records:
- check for a double-mounted frontend component;
- check whether the model called twice;
- check whether the transport retried an executed request;
- check backend idempotency constraints;
- check whether
request.idwas reused or wrongly treated as a business idempotency key.
Replay protection prevents reuse of one request id in a session; it does not make the business handler idempotent. Production writes still need database constraints or idempotency tokens.
Diagnostic steps
- Capture before/after snapshots and
changed.records. - Compare record ids, counts, and update times.
- Look for two page instances or two agents operating concurrently.
- Use a read action to confirm backend truth.
- If page and backend disagree, fix synchronization before permitting writes.
Acceptance
- Sorting, filtering, and deletion keep ids bound to the same business object.
- Old records are not callable after navigation.
- Pagination exposes total and next position.
- Retry does not write twice.
- Multi-tab conflicts have an explicit policy.
Related
Records, row actions, and change evidence, Long lists, scrolling, and offscreen actions, Context model.

