[BUG] Workflow-tool agent() subagents omit x-claude-code-agent-id / parent-agent-id (Task subagents are tagged)

Resolved 💬 6 comments Opened Jun 10, 2026 by ajcasagrande Closed Jun 10, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported.
  • [x] This is a single, focused bug report.

Describe the bug

The agent-identification headers (x-claude-code-agent-id / x-claude-code-parent-agent-id) are correctly set on Task/Agent-tool subagent requests, but not on agents spawned by the Workflow tool's agent() / parallel() / pipeline() fan-out. Workflow-spawned requests carry only the parent conversation's x-claude-code-session-id, so at the header level they are indistinguishable from top-level conversation traffic. A single workflow that fans out N concurrent agents therefore collapses into one unattributable stream at any proxy/gateway.

Steps to Reproduce

  1. Point Claude Code at a request-logging proxy (e.g. ANTHROPIC_BASE_URL) so outgoing request headers can be inspected.
  2. In one session, trigger parallel agents two ways:
  • Task tool — a prompt that spawns concurrent subagents (e.g. several parallel Explore agents).
  • Workflow tool — a dynamic workflow whose script fans out, e.g.

``js
const out = await parallel(items.map(x => () => agent(
research ${x}, { schema: S })))
``

  1. At the proxy, group the captured requests by x-claude-code-agent-id.

Expected behavior

Every in-process subagent — Task or Workflow — carries x-claude-code-agent-id (and x-claude-code-parent-agent-id when nested). The LLM-gateway docs describe the header as present "for requests made by an in-process subagent or teammate," and workflow agent() calls spawn in-process subagents, so they should be tagged the same way.

Actual behavior

Only Task/Agent-tool subagents are tagged. Workflow agent() requests carry neither header — same session, no agent identity.

Two requests from the same session, side by side (session id redacted):

Task subagent — tagged ✅

anthropic-version:         2023-06-01
x-claude-code-session-id:  <SESSION_UUID>
x-claude-code-agent-id:    <AGENT_ID>

Workflow agent() — not tagged ❌

anthropic-version:         2023-06-01
x-claude-code-session-id:  <SESSION_UUID>
(no x-claude-code-agent-id, no x-claude-code-parent-agent-id)

Impact

  • Any cost/token attribution keyed on x-claude-code-agent-id under-counts workflow fan-out — every workflow agent's usage rolls up to the parent conversation.
  • The parallel agent tree (who spawned whom) can't be reconstructed for workflows.
  • I have not observed x-claude-code-parent-agent-id populated on any request, so header-based parent→child linkage is unavailable even for Task subagents — possibly the same root cause.

Possible scope

From the proxy's perspective it looks like the per-agent context that populates these headers is established on the Task/Agent-tool spawn path but not on the Workflow spawn path — workflow-spawned requests appear to inherit the (empty) top-level agent identity. If the same context were set when a workflow spawns an agent, the existing header logic should cover it.

Environment

  • Claude Code (claude-cli) — observed on 2.1.165 and 2.1.167
  • Observed via an API-logging proxy; reproducible across platforms (headers are client-set)

References

  • #49207 — original agent-id header feature (shipped in 2.1.139); this is a coverage gap in it.
  • LLM-gateway / monitoring docs describing X-Claude-Code-Agent-Id / X-Claude-Code-Parent-Agent-Id.

View original on GitHub ↗

This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗