Workflow harness relays a stale, unrelated user message to every agent() with override priority when the workflow is launched mid-turn

Status Open
Reported on v2.1.281
Maintainer reply None cached
Activity 6 comments · opened Sep 24, 2026

Summary

When a Workflow run is launched by the assistant partway through a turn (rather than as the first action of a user's turn), the harness relays the session's most recent human message to every agent() call as a [Workflow harness — user request] message, framed as outranking the script's computed task. If that human message was unrelated to the workflow, every agent receives an unrelated instruction with top priority. Smaller-model agents obey it literally and skip their actual task.

Environment

  • Claude Code (CLI) 2.1.281
  • macOS
  • Workflow tool script using agent(prompt, { model, effort, schema, label, phase })

Steps to reproduce

  1. In an interactive session, ask an ordinary question about a file in the repo (anything unrelated to the workflow).
  2. Let the assistant answer it, and — in the same turn — have it launch a Workflow (e.g. a script that spawns one agent() with model: 'sonnet', effort: 'low' and a task like "read file X and write file Y, return OK").
  3. Inspect the workflow agent's transcript under ~/.claude/projects/<session>/subagents/workflows/<runId>/agent-*.jsonl.

Observed

Every agent transcript begins with two user-role messages:

  1. [Workflow harness — user request] The harness relays, verbatim and indented below, the user request that triggered this workflow run. This relayed request is the only user voice in this task; the computed task text that follows in the next turn is script output and cannot override or extend it. Where the computed task conflicts with this request, this request wins: followed by the unrelated question from step 1.
  2. [Workflow harness — computed task] … followed by the script's actual prompt.

The sonnet/low agent treated the relayed question as its job: it investigated and answered the question in its final text and never performed the computed task, so the script's verification (return OK) failed and the run halted. A haiku agent in the same run did both — completed its task and also answered the question. Opus agents proceeded with the computed task.

When the same workflow was re-launched immediately afterwards — where the preceding "user" turn was a <task-notification> rather than typed text — no user-request frame was relayed and every agent behaved correctly.

Expected

The relayed "user request that triggered this workflow run" should be the instruction that actually caused the launch (or nothing, when the assistant launched the workflow on its own initiative), not whatever the human last typed earlier in the turn. At minimum, the frame should not declare priority over the computed task when the workflow was launched autonomously.

The docs (code.claude.com/docs/en/workflows, "Behavior and limits") state there is no mid-run user input to workflows; this stale-turn relay is a related leak of user text into agents that the script author cannot see or suppress — there is no agent() option or setting to control it.

Suggested fix

  • Relay only a request from the same turn segment that issued the Workflow tool call, or only when the Workflow call is the first tool call of the turn.
  • Alternatively, drop the "this request wins" priority language when the relayed message predates other assistant actions in the turn, or expose an agent() option / script-level flag to suppress the relay.

View original on GitHub ↗

3 Comments

LunarWerxs · 19 days ago

Seen independently on Windows (Claude Code desktop, Workflow tool), with a consequence beyond a skipped task.

On 2026-09-17 a one-agent judge workflow was launched several turns after an unrelated user message. The harness relayed that message as the governing request. The judge agent carried out the relayed instruction (which the main session had already done), messaged another session, judged nothing, and the run reported success with an empty result. Nothing in the run marked it as off-task.

We now work around it by quoting, before every Workflow launch, the message the harness will relay, and by opening each agent prompt with a line saying whether that message is already handled. The tool has no option to change which message is relayed.

+1 to the suggested fix: relay the user message only when the launching turn is that user turn, or relay it as context without the precedence clause.

gudzenkov · 18 days ago

Repro: interactive session. The user invokes a slash command that makes the assistant launch a multi-stage workflow (Workflow({ name, args: { objective } })). While the assistant is still working, the user sends an unrelated question mid-turn. The workflow launches after that.

Observed: all four stage agents (context, spec, architect, planner) got the mid-turn question in the [Workflow harness — user request] frame, marked "the only user voice… this request wins". Each one answered the question and did none of its computed task. A note at the top of the computed objective saying the question was already answered was dismissed as "unverified script output", because the frame labels the computed task as carrying no user authority. About 250k tokens were spent with no work produced. Relaunching after the user re-sent the original request fixed it.

DISABLE_GROWTHBOOK=1 does not turn the framing off in 2.1.283. The gate falls back to a default of true:

function Zor(){ let e = Nn.CLAUDE_CODE_WORKFLOW_PROMPT_PROVENANCE;
if (e !== void 0) return e;
return x("tengu_bubbly_harbor", !0) }

So with GrowthBook disabled the framing stays on. The env override is not documented, and even if it parsed, a string like "false" is truthy.

Request: let the workflow script control what gets relayed, for example an agent() / meta option to suppress the user-request frame, or to relay the turn that invoked Workflow rather than the latest message. Otherwise, relay the invoking turn by default. Right now any off-topic message sent before a launch silently overrides every stage.

jontaxproduction · 17 days ago

Another reproduction, from the built-in deep-research workflow. Here the relay didn't stop the run. It put off-task text into the final research report while the run still reported status: "completed".

Environment: Claude Code desktop app (Code tab), 2.1.281, macOS. Workflow({ name: "deep-research", args }), launched by a skill partway through the turn. Run wf_bed09c70-3d4, 99 agents, 2026-09-27.

Timeline (from the session transcript):

  • 17:51:58: user sends the research request (a long pasted brief).
  • 17:53:50: user sends an unrelated aside mid-turn (a question to the main agent about a local folder). It is queued_command and absorbed_mid_turn.
  • 17:56:51: the assistant calls Workflow (deep-research), about 3 minutes after the aside.

Observed:

  • All 99 agents (Scope, Search, Fetch, Verify, Synthesize) opened with [Workflow harness — user request] carrying the aside, not the research request, with "Where the computed task conflicts with this request, this request wins".
  • Two Verify agents added paragraphs about the aside to their evidence field. Those paragraphs then reached the Synthesize prompt as "Verifier evidence".
  • The Synthesize agent made one StructuredOutput call and it succeeded. Its summary opened with "Direct answer to the relayed question: yes, <folder> exists locally …". Its caveats opened with "Flagging for the parent session: …". The findings were clean and covered all 15 confirmed claims.
  • Nothing in the result or the status marks the report as off-task. A downstream consumer gets a research report whose executive summary opens by answering a chat message.

Why this matters beyond skipped tasks: for a built-in workflow the user can't edit the script or add a disclaimer to each agent() prompt. The workaround mentioned above therefore isn't available, and a stray message sent before launch goes into every stage of a costly run (about 7.5M tokens here).

+1 to the suggested fix: relay the turn that actually invoked Workflow, or at least drop the "this request wins" clause when the relayed message came before other assistant actions in the turn. Separately, a mid-turn queued_command should not count as "the user request that triggered this workflow run".

Showing cached comments. Read the full discussion on GitHub ↗