You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A PreToolUse hook that returns {"decision": "block"} reliably stops normal tools
(write_to_file, run_command, ...). It does not stop invoke_subagent: the hook
command is executed, its stdout returns block, and the sub-agent is created regardless.
Since hooks are the only enforcement mechanism available (there is no flag to disable
sub-agent spawning, cf. #241), this means sub-agent creation currently cannot be
restricted at all in non-interactive runs.
Environment
agy --version -> 1.1.4 (Linux x86_64; also reproduced on 1.1.1)
{ "decision": "block", "reason": "This tool is not available here." }
Steps to reproduce
Install the hook above (matcher *), returning block when toolCall.name === "invoke_subagent" and allow for everything else.
Run a non-interactive turn that asks the model to spawn a sub-agent: agy -p 'Use invoke_subagent to spawn a subagent that replies GATE_TEST_3131.'
Expected
invoke_subagent is refused and the model is told why — the same behaviour every other
blocked tool gets.
Actual
The hook command runs (its own logging confirms it was invoked with the invoke_subagent call) and answers block — and the CLI creates the sub-agent anyway.
The transcript shows:
INVOKE_SUBAGENT Created the following subagents:
{ "conversationId": "8c3e6bef-8dad-4ec5-81a5-dd2eadb33a8a", ... }
and the model itself reports: "The native invoke_subagent tool was not refused;
the call succeeded and successfully spawned the subagent."
Control test (the hook itself works)
Same hook, same session, same --dangerously-skip-permissions, returning the identical block for a file write:
write_to_file -> blocked
model: "The attempt to write the file /tmp/... was refused. When calling the
write_to_file tool, the execution was blocked by the system"
...and the file is genuinely not created. So the hook is wired correctly and its block
is honoured — for invoke_subagent specifically it is not.
The same bypass is observed for define_subagent / manage_subagents.
Suggested fix (either would solve it)
Honour PreToolUseblock for invoke_subagent / define_subagent / manage_subagents, exactly as for other tools; or
Summary
A
PreToolUsehook that returns{"decision": "block"}reliably stops normal tools(
write_to_file,run_command, ...). It does not stopinvoke_subagent: the hookcommand is executed, its stdout returns
block, and the sub-agent is created regardless.Since hooks are the only enforcement mechanism available (there is no flag to disable
sub-agent spawning, cf. #241), this means sub-agent creation currently cannot be
restricted at all in non-interactive runs.
Environment
agy --version-> 1.1.4 (Linux x86_64; also reproduced on 1.1.1)agy -p "<prompt>" --dangerously-skip-permissions --add-dir <dir><dir>/.agents/hooks.jsonwith an explicittimeout:{ "hooks": { "PreToolUse": [ { "matcher": "*", "hooks": [{ "type": "command", "command": "node /path/to/hook.js", "timeout": 2700 }] } ] } }The hook command prints, on stdout:
{ "decision": "block", "reason": "This tool is not available here." }Steps to reproduce
*), returningblockwhentoolCall.name === "invoke_subagent"andallowfor everything else.agy -p 'Use invoke_subagent to spawn a subagent that replies GATE_TEST_3131.'Expected
invoke_subagentis refused and the model is told why — the same behaviour every otherblocked tool gets.
Actual
The hook command runs (its own logging confirms it was invoked with the
invoke_subagentcall) and answersblock— and the CLI creates the sub-agent anyway.The transcript shows:
and the model itself reports: "The native
invoke_subagenttool was not refused;the call succeeded and successfully spawned the subagent."
Control test (the hook itself works)
Same hook, same session, same
--dangerously-skip-permissions, returning the identicalblockfor a file write:...and the file is genuinely not created. So the hook is wired correctly and its
blockis honoured — for
invoke_subagentspecifically it is not.The same bypass is observed for
define_subagent/manage_subagents.Suggested fix (either would solve it)
PreToolUseblockforinvoke_subagent/define_subagent/manage_subagents, exactly as for other tools; or-pruns #241 — a way to disable sub-agent spawning for a run.Related: #528, #241, #156.