basquetWi + New ticket
mars MARS-730

Transient fetch failure on practica /editar has no retry or draft; user remedy is delete

Backlog low unassigned

A transient client-side fetch failure on the practica EDIT route has no retry and no draft preservation, and the remedy the user reaches for is DELETE. Triaged from an applog alert, 2026-09-12. THE INSTANCE, end to end, reconstructed from practicasArchive rather than inferred. Student 9dae1821 (Android Chrome, mobile) created practica 8995583f at 22:38:20Z - archive row archiveSeq=11847, reason public:practica-create. Opened /mi-cursada/8995583f/editar. At 22:42:40Z the client threw TypeError "Failed to fetch" (appEvents a15af120, level=warn, category=client, action=unhandled-error, appVersion 2.79.74, isSkewRetry=false). TEN SECONDS LATER, at 22:42:50Z, the practica was soft-deleted through the app's own path - archiveSeq=11848, reason self:practica-self-delete, archivedBy the student themself. There is NO UPDATE archive row between the two, so THE EDIT NEVER SAVED. The record carried real content: reportedPracticeDate 2026-05-04, historia clinica 14895381. No replacement practica was created that evening, or at all. NOT AN APPLICATION DEFECT, and this is stated as a bound rather than a dismissal. "Failed to fetch" is a browser network-layer failure: the request never completed, so there is nothing server-side to have gone wrong, and nothing did - zero server error rows in the window, consistent with the two clean MARS-691 windows covering 09-10..09-12. appVersion was current and isSkewRetry=false, so this is not the skew-reload path either. The app behaved as written. BASE RATE, so this is not read as new: 14 events matching errorMessage='Failed to fetch' in 30 days, across 5 DISTINCT users, 12 of 14 on mobile. Steady, low, mobile-skewed - the signature of flaky mobile connectivity, not a regression. One user accounts for 7 of the 14 over three weeks. Nothing here spikes. SO WHY A ROW AT ALL. Because the USER-VISIBLE outcome was data abandonment, and that is invisible to every instrument we have except this one. We caught it only because the delete is RECORDED - the archive trigger wrote the reason and the actor, so the abandonment left a trace. The ordinary case does not: a user who hits this and simply closes the tab writes no row at all, and our 14-event count is therefore a FLOOR on how often this happens, never a measurement of it. I am not able to say how much larger the real number is, and nothing currently deployed could tell me. WHAT THE 10-SECOND GAP DOES AND DOES NOT ESTABLISH. It is suggestive, not probative. The user may have been deleting a mis-entered practica regardless and the error is coincidental. Two facts push against pure coincidence - the edit never saved, and no replacement was created - but neither closes it. Treat the causal link as UNPROVEN; the design gap below stands on its own either way, because a transient fetch failure with no retry is worth fixing whether or not it caused this particular delete. THE GAP. On a fetch failure the edit form surfaces the error but keeps no draft and offers no retry, so the user's state is: a practica that exists, an edit that did not apply, and no obvious way forward except to remove it and start over. On a mobile connection dropping mid-session that is a foreseeable path, not an exotic one. DIRECTION, NOT A SPEC - whoever picks this up should decide the shape. Candidates: a retry affordance on the failed submit; client-side draft retention across a failed save; distinguishing "could not reach the server" from "the server rejected this" in the copy, since only the first is worth retrying. Do NOT respond by making the delete harder to reach - deleting your own erroneous practica is legitimate and the friction belongs on the failure path, not on the remedy. INSTRUMENTATION NOTE worth keeping: errorMessage is a TOP-LEVEL COLUMN on appEvents, not a key in the detail jsonb (detail carries os/browser/isMobile/isViewAs/matchedBy/isSkewRetry/serverEventId). A predicate written against the jsonb returns a confident zero here. Same trap recorded on MARS-729.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 4w ago
  • wi-cli-venus note · 4w ago
    Create-route twin seen 2026-09-13 23:03Z (/practicas/nueva, mobile, no práctica ever saved), recorded on MARS-679. One fix should cover both routes.
bug
4w ago by wi-cli-venus
4w ago