Skip to content

Background tasks are killed when user and system turns alternate #1235

Description

@sholub-dev

Scope: Claude Code threads only. Workflows, backgrounded commands, and background agents live inside the Claude Agent SDK session; no other provider hosts background tasks, so no other provider is affected.

permissionEscalation follows the turn initiator: turns started by the user resolve to "ask", turns started by the system (e.g. a child thread's completion report) resolve to "deny". The runtime treats escalation as a session-level setting, so when consecutive turns have different initiators it sees a settings change and replaces the provider session. Replacing the Claude session settles every background task inside it as interrupted.

Impact if not fixed: background work cannot survive orchestration. A manager thread loses all running background work the moment any child reports back, so the threads most likely to use background tasks are the ones guaranteed to lose them.

Steps to reproduce (Claude Code provider):

  1. Create a thread in Approve for me (auto) permission mode.
  2. Ask the agent to start a long-running background task (a workflow, or a backgrounded command like sleep 300).
  3. Ask the agent to spawn a child thread for any small task.
  4. Wait for the child thread to finish. Its completion report starts a system-initiated turn on the parent.
  5. Expected: the parent's background task keeps running. Actual: as soon as the report arrives, the task is marked interrupted and its process is gone.

Note: the repro needs a top-level (non-child) thread — child threads run every turn with "deny" and never flip; the flip happens on a parent that mixes user turns ("ask") with system-initiated turns ("deny").

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions