[Bug]: A queued message runs under the modes of the last message you sent, not the ones it was sent with#31290

opened5d agobyEEntrpi

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

Web client, Claude. In Settings, turn plan mode on and set Follow-up behavior to "Queue". With the default "Steer", Claude sends join the running turn instead of queueing.

  1. Start a long turn.
  2. Switch to Plan mode (Shift+Tab), then send A. It queues.
  3. Switch back to Default mode, then send B. It also queues.
  4. Let the turn end.

Expected behavior

A runs in Plan mode, B in Default mode.

Actual behavior

A runs in Default mode. Claude's session init for A's turn reports permissionMode: "bypassPermissions". A Plan-mode send to an idle thread in the same session starts with permissionMode: "plan".

Cause: each send first sets the thread's modes as separate commands (persistThreadSettingsForNextTurn in ChatView.tsx), even when the message only queues. startNextQueuedRun (Orchestrator.ts) starts a queued run under the thread's modes at that moment. So every queued message runs under the modes of the last send.

From the code, the runtime (permission) mode follows the same path. A message queued under a stricter mode can then run in "Full access" if a later send switched the thread back. I verified only the plan-mode case live.

Queued runs already keep the provider and model they were sent with (see #19376). Modes are the exception.

Related: #29632 (the picker shows an unsent mode) and #30162 (apply picker changes at once). Applying changes at once fixes what the picker shows, but a queued message still runs under whatever mode the thread has when it starts.

Impact

Major degradation or frequent failure

Version or commit

main @ 935818e422

Environment

macOS 26.5, web client in Chromium, Claude Haiku 5.5

Logs or stack traces

shell
1# Provider log: Claude query.open / session init permissionMode per turn
204:32:01.071Z plan # control: Plan-mode send to an idle thread
304:43:12.796Z A offered # queued in Plan mode; previous turn ended 04:43:12
404:43:13.157Z bypassPermissions # A's turn
504:43:15.959Z bypassPermissions # B's turn (queued in Default mode, correct)