[Bug]: A scheduled run cannot mark its own thread unread: mark_unread rejects while the run is active#24136

opened6d agobyRrenemifsud

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

  1. In a thread, ask the agent to create a scheduled task bound to that thread (schedule_task, default bindToCurrentThread). Its prompt should end by calling t3_thread_organize with action: "mark_unread" on the same thread, so the user notices the result.
  2. Settle the thread from the UI before the trigger time.
  3. Wait for the scheduled run.

Expected behavior

The run can flag its own result. mark_unread either succeeds, or takes effect when the run completes, the way settle on the calling thread does (settlesWhenTurnEnds: true).

Actual behavior

The call is rejected:

1OrchestratorMcpFailure orchestration_error: Thread <id> has no completed run to mark unread.

The run calling it is the thread's active run, so there is never a completed run to mark while the agent can still act. A scheduled run therefore has no way to mark its own output unread. settle handles the same timing with a deferred settlesWhenTurnEnds, so mark_unread could do the same.

A related point, which may only need documenting: the scheduled run did fire into the settled thread, and by the run's first t3_thread_read the thread already showed settled: false, settledAt: null. So delivery unsettles the thread. That is useful, but neither the schedule_task nor the t3_thread_organize description says so. Agents add their own unsettle step, then reach for mark_unread to make sure the user sees the result. Reproduced three times with the thread settled before the trigger.

Impact

Minor bug or occasional failure

Version or commit

0.1.3-nightly.20261023.3553

Environment

macOS (Darwin 25.3.0), desktop. Claude provider.

Synced from GitHub

Screenshot of the thread settled before the scheduled trigger. It was taken just before the third reproduction fired at 16:03 local time:

Thread showing "Settled just now" before the scheduled run fired

At 16:03 the scheduled run started in this same thread. Its first t3_thread_read returned settled: false and settledAt: null, before the run itself had changed anything, so delivering the run is what unsettled the thread.