PreToolUse hooks lack parallel tool call grouping context

Resolved 💬 4 comments Opened Apr 20, 2026 by Nubaeon Closed May 27, 2026

Problem

When Claude Code sends multiple tool calls in a single message (parallel tool calls), each PreToolUse hook fires as an independent subprocess invocation. The hook receives no information about whether the current tool call is part of a parallel batch, how many other calls are in the batch, or what those other calls are.

Impact

Hooks that maintain state or make gating decisions based on tool call patterns cannot distinguish between:

  • 3 parallel Read calls (a single investigation action)
  • 3 sequential Read calls over time (potentially different intent)

This matters for:

  • Rate limiting / nudging — a hook counting tool calls to suggest checkpoints sees 3 calls when the user's intent was 1 action
  • Permission gating — a hook that gates praxic tools can't assess whether a parallel batch is coherent (e.g., Read + Read + Edit — the reads are noetic, the edit is praxic, but they're one logical action)
  • Audit logging — hooks recording tool usage patterns get fragmented data

Proposed Solution

Include parallel batch context in the hook input:

{
  "toolName": "Read",
  "toolInput": { "file_path": "/src/main.py" },
  "parallelBatch": {
    "batchId": "batch_abc123",
    "batchSize": 3,
    "batchIndex": 0,
    "siblingTools": ["Read", "Read", "Grep"]
  }
}

Alternatively, a simpler approach — just batchSize and batchIndex:

{
  "toolName": "Read",
  "toolInput": { "file_path": "/src/main.py" },
  "batchSize": 3,
  "batchIndex": 0
}

batchSize: 1 (or field absent) means sequential/single call. batchSize > 1 means this is part of a parallel batch.

Context

We build Empirica, an epistemic measurement framework that uses PreToolUse hooks for tool classification (noetic/read-only vs praxic/write). The lack of parallel batch context means our sentinel hook evaluates each call independently, which works but loses the signal that parallel calls represent a single logical action.

This is a minor enhancement request — the current behavior is functional, just information-limited.

View original on GitHub ↗

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