Skip to content

fix(multiuser): do not let progress status of one user's session leak into another's#9353

Open
lstein wants to merge 3 commits into
invoke-ai:mainfrom
lstein:fix/gallery-autoswitch-cross-user
Open

fix(multiuser): do not let progress status of one user's session leak into another's#9353
lstein wants to merge 3 commits into
invoke-ai:mainfrom
lstein:fix/gallery-autoswitch-cross-user

Conversation

@lstein

@lstein lstein commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

In multiuser mode, one user's generation activity leaked into other users' personal UI. The most visible symptom: when an unprivileged user generated an image to their private board, an admin's selected board would switch to that user's board and display the new image. Beyond that, other users' activity animated everyone's progress bar, busy favicon, and invoke-button spinner, cleared in-flight progress displays, and (for admins) raised other users' failure toasts.

Principle applied throughout: events may keep other users' caches fresh (and admins may observe all activity in the queue list), but personal UI — board/image selection, progress indicators, toasts — only follows the current user's own actions. Single-user mode is unaffected.

Changes

Gallery auto-switch

  • onInvocationComplete now only auto-switches boards / selects the new image when the completion event belongs to the current user. Admins receive all users' completion events (needed to keep their gallery caches fresh) but no longer have their selection hijacked.

Invocation event routing

  • InvocationProgressEvent is emitted only to the owner's room. It drives personal UI exclusively (global progress bar, workflow editor current-image node, image viewer progress image), and no admin UI consumes other users' progress. This also removes the previous image-stripped admin copy.
  • Started/complete/error events still go to owner + admins, but via a single emit to a room list. python-socketio dedupes recipients, so an admin owner (including the system user in single-user mode) now receives exactly one copy instead of two — the duplicate delivery previously clobbered the owner's progress image with the stripped admin copy and processed completions twice.
  • Another user's completion no longer clears the current user's progress indicator.

Queue status counts

  • The status endpoint now returns user_pending/user_in_progress for every caller, admins included. A new fail-closed is_admin flag on get_queue_status() disables current-item redaction for admins so they keep visibility of other users' current item while gaining their own counts; user_id without the flag behaves exactly as before.
  • The progress bar, busy favicon/tab title, and floating invoke button spinner prefer the per-user counts, so they only react to the user's own queue items.
  • Queue status embedded in socket events never carries per-user counts; when patching the RTK cache from an event, previously-fetched per-user counts are retained instead of being nulled.

Model load events

  • ModelLoadStartedEvent/ModelLoadCompleteEvent now carry the user_id whose action triggered the load (threaded from the invocation context's queue item and the prompt-expand / image-to-prompt / model-convert endpoints) and are routed to that user's room instead of broadcast to every client. Previously any user's model load forced everyone's progress bar into indeterminate mode. Install/download events remain broadcast (the model manager UI is not per-user).
  • schema.ts / openapi.json regenerated for the new event field.

Terminal-status side effects

  • The failure toast and progress reset on completed/failed/canceled queue items now fire only for the current user's own items. Admins previously got other users' error toasts; failures remain visible to admins in the queue list.

Testing

  • New backend tests: invocation/model-load event routing (owner-only progress, single deduped emit to owner+admin, owner-only load events, installs still broadcast), admin queue-status scoping (own counts + unredacted current item).
  • New frontend tests: ownership gating in onInvocationComplete (no board switch / progress clear for foreign events, caches still updated; own and single-user events unaffected), per-user count retention in queue status cache patches.
  • Full suites pass: 1212 backend, 1305 frontend; ruff/tsc/eslint/prettier clean.
  • Manually verified in a two-user multiuser setup: bystander and admin progress bars/favicons stay idle during another user's generation (including model-load phase), board selection no longer jumps, own-activity indicators and single-user behavior unchanged.

🤖 Generated with Claude Code

@github-actions github-actions Bot added api python PRs that change python files services PRs that change app services frontend PRs that change frontend files python-tests PRs that change python tests labels Jul 13, 2026
@lstein lstein changed the title fix(multiuser): scope board auto-switch, progress, and activity indicators to the user's own generations fix(multiuser): do not let progress status of one user's session leak into another's Jul 13, 2026
lstein and others added 3 commits July 12, 2026 22:39
In multiuser mode, invocation-complete events are emitted to the admin
room as well as the owner's room so that admins' gallery caches stay
fresh. The gallery auto-switch handler treated every received event as
the current user's own generation, so an admin's selected board would
jump to another user's board whenever that user generated an image.

Gate the auto-switch (board + image selection) on the event's user_id
matching the logged-in user. Cache updates (board totals, image name
lists) still run for all received events. Single-user mode, where there
is no current user, is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Invocation progress events drive personal UI only (the global progress
bar, the workflow editor's current-image node, the image viewer's
progress image). Emitting them to the admin room made an admin's
progress display animate and sawtooth in response to other users'
generations. No admin-facing feature consumes other users' progress, so
emit progress events to the owner's room only.

The remaining invocation events (started, complete, error) still go to
admins since the gallery cache updates depend on them, but now via a
single emit to [user room, admin room]. python-socketio dedupes
recipients across a room list, so an admin who owns the queue item -
including the "system" user in single-user mode, which is also an
admin - receives exactly one copy instead of two. The old double
delivery meant the second, image-stripped copy of a progress event
clobbered the owner's own progress image, and completion events were
processed twice.

On the frontend, an invocation-complete event now only clears the
progress indicator when the event belongs to the current user, sharing
the ownership check introduced for gallery auto-switch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…iuser mode

Three related fixes so that one user's generation activity no longer
animates other users' (including admins') personal UI:

1. The queue status endpoint now returns per-user counts for every
   caller, admins included. A new is_admin flag on
   get_queue_status() disables current-item redaction for admins so
   they keep visibility of other users' current item while gaining
   their own user_pending/user_in_progress counts. Redaction remains
   fail-closed for callers that pass user_id without the flag.

   The frontend progress bar, busy favicon/tab title, and floating
   invoke button spinner now prefer the per-user counts over the
   global counts, so they only react to the user's own queue items.
   Queue status embedded in socket events never carries user counts;
   when patching the cache from an event, the previously-fetched
   per-user counts are retained instead of being nulled out.

2. Model load events now carry the user whose action triggered the
   load (threaded from the invocation context's queue item and the
   utility/convert endpoints) and are routed to that user's socket
   room instead of being broadcast to every connected client. These
   events only feed the loading-models spinner, which is personal UI.
   Model install/download events remain broadcast. schema.ts and
   openapi.json regenerated for the new event field.

3. On a queue item reaching a terminal status, the failure toast and
   progress indicator reset now only fire for the current user's own
   items - admins receive these events for all users and previously
   got other users' error toasts and had their in-flight progress
   display cleared.

Single-user mode is unaffected throughout: there is no current user
in the frontend auth state, the sole "system" user is in its own
user room, and its per-user counts equal the global counts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lstein lstein force-pushed the fix/gallery-autoswitch-cross-user branch from 8210b50 to c13e1e4 Compare July 13, 2026 02:39
@lstein lstein added the 6.14.x label Jul 13, 2026
@lstein lstein moved this to 6.14.x Theme: USER EXPERIENCE in Invoke - Community Roadmap Jul 13, 2026
@lstein lstein assigned Pfannkuchensack and unassigned JPPhoto Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.14.x api frontend PRs that change frontend files python PRs that change python files python-tests PRs that change python tests services PRs that change app services

Projects

Status: 6.14.x Theme: USER EXPERIENCE

Development

Successfully merging this pull request may close these issues.

3 participants