After /record/start returns 200, GET /sessions/{id} once still read "confirmed" (D116) #845

Closed
opened 2026-09-26 15:32:59 +00:00 by claude-bot · 2 comments
Collaborator

Seen once in J4 on desktop, during a loaded run in lane 7's integration (#733). It passed in every other run and on the other projects.

POST /api/sessions/{id}/record/start returned 200, and the backend log shows session_service.start_by_recording's conditional UPDATE committing inside that request. Yet the test's GET /api/sessions/{id} straight after still returned status: "confirmed".

Worth checking:

  • whether the start endpoint commits before responding, or only on the dependency's teardown after the response is sent;
  • whether the GET could hit a different connection before that commit is visible;
  • any response caching on the session GET.

If the commit happens after the response, the fix is to commit explicitly before returning.

Lane 5's code (#731, D116).

Seen once in J4 on desktop, during a loaded run in lane 7's integration (#733). It passed in every other run and on the other projects. `POST /api/sessions/{id}/record/start` returned 200, and the backend log shows `session_service.start_by_recording`'s conditional UPDATE committing inside that request. Yet the test's `GET /api/sessions/{id}` straight after still returned `status: "confirmed"`. **Worth checking:** - whether the start endpoint commits *before* responding, or only on the dependency's teardown after the response is sent; - whether the GET could hit a different connection before that commit is visible; - any response caching on the session GET. If the commit happens after the response, the fix is to commit explicitly before returning. Lane 5's code (#731, D116).
Author
Collaborator

Investigated (2026-09-26): the server side is correct. session_service.start_by_recording calls db.commit() itself before returning, and before the router builds its response. There's no caching on GET /api/sessions/{id}. A new two-connection regression test in #847's branch (test_start_by_recording_commits_before_a_fresh_read_sees_it) proves a fresh reader sees in_progress at once.

So the one J4 observation, a confirmed read right after a 200, has another cause. The likeliest candidates:

  • the spec read through something that raced the start;
  • a backend worker died and restarted mid-step, since the same run was under the load that produced #841.

Leaving this open at low priority. If it recurs, the J4 log around the start step is the place to look.

**Investigated (2026-09-26): the server side is correct.** `session_service.start_by_recording` calls `db.commit()` itself before returning, and before the router builds its response. There's no caching on `GET /api/sessions/{id}`. A new two-connection regression test in #847's branch (`test_start_by_recording_commits_before_a_fresh_read_sees_it`) proves a fresh reader sees `in_progress` at once. So the one J4 observation, a `confirmed` read right after a 200, has another cause. The likeliest candidates: - the spec read through something that raced the start; - a backend worker died and restarted mid-step, since the same run was under the load that produced #841. Leaving this open at low priority. If it recurs, the J4 log around the start step is the place to look.
Author
Collaborator

Closing with evidence (2026-10-01). Seen once, on 26 September, in a run under the load that produced #841; not seen since.

  • The server is correct: session_service.start_by_recording commits before the route builds its reply, and tests/test_table_live.py::test_start_by_recording_commits_before_a_fresh_read_sees_it (on main) proves a second connection reads in_progress at once.
  • #854 (#851, merged 26 September) made every route's database dependency commit before the response is sent (Depends(get_db, scope="function"), app/database.py), which closed the general class this report belonged to: a reply reaching the browser before its write was visible.
  • #1002 (#841) since made Redis calls time out instead of stalling a worker, the other candidate named above.
  • J4 has run on desktop, phone and keyboard on every PR since (well over a hundred runs across lanes 8 to 11 and this week's issue work) without this step failing.

If it recurs, reopen with the J4 log around the start step.

**Closing with evidence (2026-10-01).** Seen once, on 26 September, in a run under the load that produced #841; not seen since. - The server is correct: `session_service.start_by_recording` commits before the route builds its reply, and `tests/test_table_live.py::test_start_by_recording_commits_before_a_fresh_read_sees_it` (on main) proves a second connection reads `in_progress` at once. - #854 (#851, merged 26 September) made every route's database dependency commit before the response is sent (`Depends(get_db, scope="function")`, `app/database.py`), which closed the general class this report belonged to: a reply reaching the browser before its write was visible. - #1002 (#841) since made Redis calls time out instead of stalling a worker, the other candidate named above. - J4 has run on desktop, phone and keyboard on every PR since (well over a hundred runs across lanes 8 to 11 and this week's issue work) without this step failing. If it recurs, reopen with the J4 log around the start step.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#845
No description provided.