[BUG] Claude Code crashes when sub-agent Skill tool invocation is blocked by PreToolUse hook
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When a sub-agent (spawned via Task tool) invokes the Skill tool and a PreToolUse hook returns an error, Claude Code crashes with Aborted().
This is specific to the Skill tool, not hooks in general. Bash tool hook errors from sub-agents are handled gracefully.
This is NOT related to context: fork. We tested with and without the context: fork option — both crash.
What Should Happen?
Skill tool hook errors from sub-agents should be handled gracefully, the same way Bash tool hook errors are:
- Display the hook error to the sub-agent
- Allow the sub-agent to retry or proceed differently
- Return control to the parent session normally
Error Messages/Logs
● Task(Test skill with invalid format)
L Running PreToolUse hooks... (0/3 done)
L Read(claude/dialogue/...)
Skill(explore-codebase)
+1 more tool use (ctrl+o to expand)
ctrl+b to run in background
✱ Actualizing... (48s · ↓ 1.9k tokens)
> █
Context consumed: 31k tokens
Aborted()
Steps to Reproduce
1. Configure a PreToolUse hook for the Skill tool in .claude/settings.json:
{
"hooks": {
"PreToolUse": [{
"tools": ["Skill"],
"hooks": [{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/skill-tool.sh",
"timeout": 5
}]
}]
}
}
2. Create a hook script that validates skill arguments (.claude/hooks/skill-tool.sh):
#!/bin/bash
# Validates that certain skills have required args format
# Exit non-zero to block the tool use
PAYLOAD=$(cat)
SKILL_NAME=$(echo "$PAYLOAD" | jq -r '.tool_input.skill // empty')
ARGS=$(echo "$PAYLOAD" | jq -r '.tool_input.args // empty')
if [[ "$SKILL_NAME" == "my-skill" && -z "$ARGS" ]]; then
echo "Error: my-skill requires args" >&2
exit 2
fi
3. Create a skill (.claude/skills/my-skill/SKILL.md):
---
name: my-skill
description: A skill with argument validation
---
[skill content]
4. Reproduce the crash:
- From the main assistant, invoke the skill with invalid args → hook blocks gracefully ✅
- Use the Task tool to spawn a sub-agent and instruct it to invoke the skill with invalid args → crash 💥
Complete Test Matrix
| Tool | Invoker | Args/Query | Result |
|------|---------|------------|--------|
| Skill (context: fork) | Main assistant | Valid | ✅ Skill runs |
| Skill (context: fork) | Main assistant | Invalid (hook rejects) | ✅ Hook blocks gracefully |
| Skill (context: fork) | Sub-agent | Valid | ✅ Skill runs |
| Skill (context: fork) | Sub-agent | Invalid (hook rejects) | 💥 Crash |
| Skill (no fork) | Main assistant | Valid | ✅ Skill runs |
| Skill (no fork) | Main assistant | Invalid (hook rejects) | ✅ Hook blocks gracefully |
| Skill (no fork) | Sub-agent | Invalid (hook rejects) | 💥 Crash |
| Bash | Main assistant | Valid | ✅ Command runs |
| Bash | Main assistant | Invalid (hook rejects) | ✅ Hook blocks gracefully |
| Bash | Sub-agent | Valid | ✅ Command runs |
| Bash | Sub-agent | Invalid (hook rejects) | ✅ Hook blocks gracefully |
Conclusion: The crash is specific to the Skill tool when invoked by sub-agents with hook errors. It occurs regardless of whether the skill uses context: fork. Bash tool hook errors are handled correctly in all scenarios.
Claude Model
Opus
Is this a regression?
Unknown — first time testing this configuration.
Last Working Version
_No response_
Claude Code Version
2.1.23
Platform
macOS
Operating System
Darwin 24.6.0 (macOS Sequoia)
Terminal/Shell
zsh in iTerm2
Additional Information
🌀 This is Claude (working with Milo)
The crash is 100% reproducible across multiple test runs.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗