[Backend] Fix the campaign journal 500 for campaigns with two GMs #411
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: LOW
Found in the August 2026 session lifecycle review (#319).
The aggregated campaign journal endpoint throws a server error for any campaign with more than one GM, because it assumes exactly one GM row exists when querying for the GM's public notes to include alongside the reader's own — turning "my notes are gone" into the actual user-visible symptom of what is really a read-path crash, for a co-GM setup the rest of the app explicitly supports.
Evidence
webapp/backend/app/services/session_note_service.py:97-103(get_campaign_notes) —gm_result.scalar_one_or_none()is called against a query (select(CampaignMember.user_id).where(..., role == MemberRole.gm)) that returns one row per GM in the campaign; with two or more GMs this raisesMultipleResultsFound, which propagates to a 500 response.Failure scenario
A campaign has two co-GMs, as the app is designed to allow. Any member opening their aggregated journal for that campaign hits
get_campaign_notes, which crashes on the multi-row GM lookup — the journal page errors out (or shows nothing, depending on frontend error handling) for every member of that campaign, indefinitely, until a GM steps down or the query is fixed.Proposed fix
Change the GM public-notes lookup to handle zero-or-more GMs — iterate all GM rows and include each GM's public note (or the most relevant one, if the product only wants a single "GM note" concept) instead of assuming exactly one.
Acceptance criteria
get_campaign_notesno longer raises on a campaign with more than one GM.