Block a Subagent From Stopping With an Unresolved TODO

A subagent that quietly finishes with a half-done task is easy for the parent session to miss, especially in a long delegation chain. This forces the subagent to either actually finish or explicitly surface the gap instead of ending on an unresolved marker.

Subagent & Multi-Agent Safety Event: SubagentStop Claude Code Open source · Free

1. Save this as the hook script

#!/usr/bin/env python3
"""SubagentStop hook — blocks stopping if the final message contains an
unresolved TODO/FIXME marker."""
import json, re, sys

data = json.load(sys.stdin)
message = data.get("last_assistant_message", "")

if re.search(r"(?i)\b(TODO|FIXME|not implemented)\b", message):
    print("BLOCKED: final message contains an unresolved TODO/FIXME/"
          "\"not implemented\" marker. Finish it or state explicitly why it's deferred.", file=sys.stderr)
    sys.exit(2)

sys.exit(0)

Save to a path inside your project, e.g. .claude/hooks/block-subagent-stop-unresolved-todo.sh, then chmod +x it.

2. Wire it into .claude/settings.json

{
  "hooks": {
    "SubagentStop": [
      {
        "hooks": [
          {"type": "command", "command": "python3 .claude/hooks/block-subagent-stop-unresolved-todo.py"}
        ]
      }
    ]
  }
}

Before you use this

A hook runs with your local shell's permissions — review the script above before adding it, the same way you'd review any script you didn't write yourself. See our guide on hook security risks for the specific CVEs this category of feature has already produced.

Related hooks

← All hooks
FEEDBACK