Skip to content

🤖 fix: reported-task cleanup and task_send_message acquire the event and task-tree lifecycle locks in opposite orders #4072

Description

@ibetitsmike

Summary

TaskService.cleanupReportedLeafTask runs under the workspace event lock (every runtime caller reaches it through requestReportedTaskCleanupRecheck, which wraps it in workspaceEventLocks.withLock, and from stream-end finalization) and calls WorkspaceService.remove(), which takes the task-tree lifecycle lock: event -> lifecycle. task_send_message nests the other way, withTaskTreeLifecycleLock(taskId, () => workspaceEventLocks.withLock(taskId, ...)): lifecycle -> event. If a reported task's cleanup and a task_send_message to that same task interleave, both can wait on each other's lock.

Surfaced by Codex on #4058 (which only added a live-state recheck inside the existing remove() acquisition and documented the inversion). The ordering itself predates that PR.

Suggested direction

Either run reported-task removal outside the event lock (queue the removal after the event-locked section releases, with the live recheck still inside remove()'s lifecycle lock), or make the send path release the lifecycle lock before taking the event lock. One lock order for every path that touches both.


Generated with xum • Model: anthropic:claude-fable-5-1 • Thinking: xhigh • Cost: $188.37

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions