Agent-type Stop hook runs 42+ minutes despite "timeout": 240

Status Fixed / completed
Reported on v2.1.223
Maintainer reply None cached
Activity 0 comments · opened Aug 6, 2026 · closed Aug 6, 2026

Environment

  • Claude Code 2.1.223, macOS (darwin 25.5.0)
  • Hook: Stop hook, "type": "agent", configured in project .claude/settings.json

Config (abridged)

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "You are a STRICT rules-compliance reviewer... (reviews `git diff <base>..HEAD` against the repo's CLAUDE.md and rules)",
            "timeout": 240,
            "model": "claude-opus-5",
            "statusMessage": "Rules-compliance review"
          }
        ]
      }
    ]
  }
}

Full config: https://github.com/ket-sh/ket/blob/ad98921/.claude/settings.json

Expected

Per the hooks reference, timeout (seconds) is a common field and should bound the entire agent-hook run; the default for agent hooks is 60s. With "timeout": 240, the hook should be cancelled after 4 minutes, fail open, and let the stop proceed.

Observed

The Stop hook ran 42+ minutes in a single turn end. The status line showed Rules-compliance review… 2/6 · 42m 38s · ↓ 76.8k tokens (spinner counter 2/6 is itself undocumented — unclear whether it counts hooks or something else). The session's turn end was blocked the whole time.

Context that may matter for reproduction: the branch diff under review was large (a fresh git worktree, so the agent reviewed the whole merge-base..HEAD diff, six commits plus uncommitted work), and the prompt instructs several git invocations plus reading rule files.

Why it bites

Agent hooks fail open on timeout by design, so an unenforced timeout is the worst of both worlds: you cannot rely on the ceiling to bound latency, and you cannot lower it to bound latency either (that would starve the review and silently disable it). A gate that sometimes costs 40+ minutes per turn end trains users to kill it.

Questions

  1. Is timeout expected to bound the whole agent loop for type: "agent" Stop hooks in 2.1.x? (Changelog 2.1.210 mentions a hook-timeout misreport fix; this is 2.1.223.)
  2. What does the N/M counter in the hook status line count?

View original on GitHub ↗