[BUG] Claude Code crashes when sub-agent Skill tool invocation is blocked by PreToolUse hook

Resolved 💬 3 comments Opened Jan 29, 2026 by milobird Closed Feb 1, 2026

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:

  1. Display the hook error to the sub-agent
  2. Allow the sub-agent to retry or proceed differently
  3. 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.

View original on GitHub ↗

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