[Copilot speaking]
When a task's agent invokes the built-in task tool to spawn a sub-agent, the run can hang indefinitely when the sub-agent's tool calls emit permission.requested events that never receive matching permission.completed events. The eval has no API-side timeout, so it can hang for hours.
This is a known upstream bug in copilot-cli (copilot-sdk#947 / #959, "Subagents don't inherit session-defined external tools") that was fixed in copilot-cli v1.0.49-0 (2026-05-13):
Fixed: Hooks (preToolUse, postToolUse, subagentStart, subagentStop) now fire correctly for sub-agent tool calls
Waza 0.31.0 still bundles copilot_1.0.2 (see internal/embedded/zcopilot_*.zst), which predates the fix. The embedded loader hard-codes the version in internal/embedded/zcopilot_<platform>.go via embeddedcli.Setup(embeddedcli.Config{Version: "1.0.2", ...}), and there is no env-var override (the source comment in internal/execution/copilot.go explicitly states: "auto-loads the embedded copilot CLI, over using the copilot CLI on the machine"). The result is that any eval whose agent decides to use the task tool is unrunnable on stock waza.
Environment
- waza
v0.31.0 (Windows amd64, downloaded binary)
- Bundled CLI:
copilot_1.0.2 (per process name; matches internal/embedded/zcopilot_1.0.2_windows_amd64.exe.zst)
- Model:
claude-opus-4.6 (consistently autonomously spawns sub-agents for parallel reads)
- Latest available copilot-cli:
v1.0.49 (2026-05-18)
Reproduction
Any eval where the agent decides to delegate work via the task tool. In our case, a manifest-only Rust workspace eval where the agent reads ~27 Cargo.toml files; claude-opus-4.6 reliably invokes task to read them in parallel.
Run with waza --debug run … --session-log --session-dir <dir> --transcript-dir <dir> *>&1 > stdout.log, then tail the debug log.
Evidence
From a --debug log of a hung run:
type=tool.execution_start toolName=task arguments.description="Read all Cargo.toml..."
type=subagent.started remoteSessionId=<child-session-id>
type=tool.execution_start toolName=view toolCallID=tooluse_… (×27, all from sub-agent)
type=permission.requested toolCallID=tooluse_… (×19)
After this point: zero permission.completed, zero tool.execution_complete for any sub-agent call, no further events. Run stays in this state until killed (observed hangs of 1.5+ hours).
Counts at the time of kill:
tool.execution_start: 31 (3 parent + 28 sub-agent)
tool.execution_complete: 3 (the 3 parent calls before task was invoked)
permission.requested: 19
permission.completed: 3 (all from parent session, pre-task)
The diagnostic signature is unambiguous: permission.requested count grows monotonically after subagent.started fires; permission.completed count stays at whatever it was before the sub-agent spawned.
Diagnosis
Waza correctly installs OnPermissionRequest: allowAllTools on the parent session in internal/execution/copilot.go:
permRequestCallback := allowAllTools
if req.PermissionHandler != nil {
permRequestCallback = req.PermissionHandler
}
session, err = e.client.CreateSession(ctx, &copilot.SessionConfig{
OnPermissionRequest: permRequestCallback,
…
})
But when the agent invokes task, copilot-cli creates a child session for the sub-agent. The child session ID is not in the SDK's c.sessions map (only CreateSession and ResumeSessionWithOptions populate it). When the sub-agent's tool calls arrive with the child session ID, the SDK can't resolve a handler, so OnPermissionRequest is never invoked. This exact failure mode is described in copilot-sdk#947's "Current behavior" section, and the runtime fix (child→parent session resolution for tool.call, permission.request, hooks.invoke, userInput.request) shipped in copilot-cli v1.0.49-0.
Proposed fix
Bump the bundled copilot-cli from 1.0.2 to 1.0.49+ in internal/embedded/:
- Download
copilot-cli v1.0.49 platform binaries from the v1.0.49 release.
- Re-compress as
.zst and regenerate internal/embedded/zcopilot_1.0.49_<platform>.<ext>.zst + .license.
- Update
internal/embedded/zcopilot_<platform>.go files: change Version: "1.0.2" → "1.0.49", recompute CliHash.
Optional follow-up: add a WAZA_COPILOT_CLI_PATH (or similar) env var that lets the user override the embedded CLI with a locally-installed binary. This would let users unblock themselves the next time copilot-cli ships a critical fix without waiting for a waza release.
Workaround until fixed
Add a constraint to the task prompt telling the agent not to spawn sub-agents (e.g. "Do not use the task tool; read/edit files directly"). This is a hack — the eval is no longer realistic — but it unblocks runs. There is no SDK- or eval-spec-level option to disable the task tool or to force same-session execution.
[Copilot speaking]
When a task's agent invokes the built-in
tasktool to spawn a sub-agent, the run can hang indefinitely when the sub-agent's tool calls emitpermission.requestedevents that never receive matchingpermission.completedevents. The eval has no API-side timeout, so it can hang for hours.This is a known upstream bug in
copilot-cli(copilot-sdk#947 / #959, "Subagents don't inherit session-defined external tools") that was fixed in copilot-cli v1.0.49-0 (2026-05-13):Waza 0.31.0 still bundles
copilot_1.0.2(seeinternal/embedded/zcopilot_*.zst), which predates the fix. The embedded loader hard-codes the version ininternal/embedded/zcopilot_<platform>.goviaembeddedcli.Setup(embeddedcli.Config{Version: "1.0.2", ...}), and there is no env-var override (the source comment ininternal/execution/copilot.goexplicitly states: "auto-loads the embedded copilot CLI, over using the copilot CLI on the machine"). The result is that any eval whose agent decides to use thetasktool is unrunnable on stock waza.Environment
v0.31.0(Windows amd64, downloaded binary)copilot_1.0.2(per process name; matchesinternal/embedded/zcopilot_1.0.2_windows_amd64.exe.zst)claude-opus-4.6(consistently autonomously spawns sub-agents for parallel reads)v1.0.49(2026-05-18)Reproduction
Any eval where the agent decides to delegate work via the
tasktool. In our case, a manifest-only Rust workspace eval where the agent reads ~27Cargo.tomlfiles;claude-opus-4.6reliably invokestaskto read them in parallel.Run with
waza --debug run … --session-log --session-dir <dir> --transcript-dir <dir> *>&1 > stdout.log, then tail the debug log.Evidence
From a
--debuglog of a hung run:After this point: zero
permission.completed, zerotool.execution_completefor any sub-agent call, no further events. Run stays in this state until killed (observed hangs of 1.5+ hours).Counts at the time of kill:
tool.execution_start: 31 (3 parent + 28 sub-agent)tool.execution_complete: 3 (the 3 parent calls beforetaskwas invoked)permission.requested: 19permission.completed: 3 (all from parent session, pre-task)The diagnostic signature is unambiguous:
permission.requestedcount grows monotonically aftersubagent.startedfires;permission.completedcount stays at whatever it was before the sub-agent spawned.Diagnosis
Waza correctly installs
OnPermissionRequest: allowAllToolson the parent session ininternal/execution/copilot.go:But when the agent invokes
task, copilot-cli creates a child session for the sub-agent. The child session ID is not in the SDK'sc.sessionsmap (onlyCreateSessionandResumeSessionWithOptionspopulate it). When the sub-agent's tool calls arrive with the child session ID, the SDK can't resolve a handler, soOnPermissionRequestis never invoked. This exact failure mode is described in copilot-sdk#947's "Current behavior" section, and the runtime fix (child→parent session resolution fortool.call,permission.request,hooks.invoke,userInput.request) shipped in copilot-cli v1.0.49-0.Proposed fix
Bump the bundled copilot-cli from 1.0.2 to 1.0.49+ in
internal/embedded/:copilot-cliv1.0.49 platform binaries from the v1.0.49 release..zstand regenerateinternal/embedded/zcopilot_1.0.49_<platform>.<ext>.zst+.license.internal/embedded/zcopilot_<platform>.gofiles: changeVersion: "1.0.2"→"1.0.49", recomputeCliHash.Optional follow-up: add a
WAZA_COPILOT_CLI_PATH(or similar) env var that lets the user override the embedded CLI with a locally-installed binary. This would let users unblock themselves the next time copilot-cli ships a critical fix without waiting for a waza release.Workaround until fixed
Add a constraint to the task prompt telling the agent not to spawn sub-agents (e.g. "Do not use the
tasktool; read/edit files directly"). This is a hack — the eval is no longer realistic — but it unblocks runs. There is no SDK- or eval-spec-level option to disable thetasktool or to force same-session execution.