Repository navigation
Description
Saving the Manage Group page ends the clinician's active session. After a successful save, the page stores the returned group with changeGroup(updatedGroup). changeGroup is the group-switch action, and it always sets currentSession: null, because a session belongs to the group it was started in. Here the group is the same one; only its settings changed. A clinician who notices mid-assessment that an instrument is not enabled for the group, enables it on /group/manage and saves, loses the session for the subject in front of them. "Accessible Instruments" and "Remote Assignment" go disabled, and they have to start a new session, re-identifying the subject and creating a second session record.
Where
apps/web/src/store/slices/auth.slice.ts:27-29:
changeGroup: (group) => {
set({ currentGroup: group, currentSession: null, preferredGroupId: group.id });
},called with the group that is already current from apps/web/src/routes/_app/group/manage.tsx:975-978:
onSubmit: async (data) => {
const updatedGroup = await updateGroupMutation.mutateAsync(data);
changeGroup(updatedGroup);
},Reproduce
- Sign in as a group manager and start a session for any subject.
- Open Manage Group from the sidebar, tick an additional instrument (or change any setting), and save.
- Look at the sidebar.
Actual: the session is gone. "Start Session" is enabled again, and "Accessible Instruments", "Remote Assignment" and "View Current Subject" are disabled.
Expected: the session survives, and the newly enabled instrument can be administered to the same subject straight away.
Tests
apps/web/src/store/slices/__tests__/auth.slice.test.ts:it('should keep the current session when the current group is replaced by an updated copy of itself, so saving group settings does not end an assessment'), plusit('should still end the session when switching to a different group').testing/src/specs/group-manage.spec.ts: start a session, save a settings change on Manage Group, and assert the Accessible Instruments nav item is still enabled.
Suggested fix
Clear currentSession in changeGroup only when group.id !== get().currentGroup?.id. Alternatively, add a separate updateCurrentGroup(group) action that replaces the group object without touching the session, and call that from manage.tsx.
Activity
joshunrau commentedon Oct 26, 2026
Still reproduces on
main(d86740e). No commit has touched the cited files since this was filed. #1660 touchesauth.slice.ts, but only its CASL types.Take the second suggested fix
Add
updateCurrentGroupand keepchangeGroupas the switch action. MakingchangeGroupconditional leaves a second bug in place.onSubmitcallschangeGroupwhenever the PATCH resolves. Say a manager switches from group A to group B in the group switcher while a save for A is in flight. When the response lands, it switches them back to A. Thekeyatmanage.tsx:972remounts only the form, notRouteComponent, and themutateAsyncpromise resolves either way. A conditionalchangeGroupsees a different id there and switches anyway.updateCurrentGroup(group)replacescurrentGrouponly whengroup.idmatches the current group's id, and leavescurrentSessionandpreferredGroupIdalone. Declare it inAuthSlice(apps/web/src/store/types.ts:12-19). With #1719 it also replaces the matching entry incurrentUser.groups.Call it from
useUpdateGroupMutation'sonSuccess, as the plan on #1719 does, rather than frommanage.tsx.GroupEmailTemplates.tsx:123-135saves through the same hook and never updates the store.onSubmit(manage.tsx:975-978) then only awaitsmutateAsync.Tests
auth.slice.test.ts: the second test proposed above already exists at:111-115. Add the keep-the-session test. Also add one where a saved group that is not the current one leavescurrentGroupunchanged.manage.test.tsx:613-618asserts thatchangeGroupreceives the saved group. That assertion moves touseUpdateGroupMutation.test.ts, and thechangeGroupmock atmanage.test.tsx:16and:41-42goes. Two suites run the real hook, so their fake stores need the new action:useUpdateGroupMutation.test.ts:12andGroupEmailTemplates.test.tsx:19.group-manage.spec.ts.currentSessionis not inPERSISTED_KEYS(apps/web/src/store/index.ts:19-24), so anypage.gotoafter the session starts ends it. That rules outpage.goto('/group/manage')as at:111, andgetPageModeltoo.getPageModelalso signs in again as the default role (testing/src/support/fixtures.ts:148-151). Sign in withisolatedGroupManager(), because the test changes its group. Open Start Session withnew StartSessionPage(page)andgoto, asstart-session.spec.ts:270-271does, and start the session as:294-298does. Reach Manage Group through the sidebar (group-manage.spec.ts:134-135) and save a change. Navigate once more, then assert thatnav-button-/instruments/accessible-instrumentsis enabled. The extra navigation is needed because the nav'sdisabledstate settles in an effect (start-session.spec.ts:300-303).Land this in one PR with #1719 and #1642, one commit per issue. All three change
useUpdateGroupMutationand its tests.Triage note written with Claude Code. Code references point at
main@d86740e.