tool_use_id missing from hook payloads in headless/bypassPermissions mode

Resolved 💬 2 comments Opened Jan 14, 2026 by sunholo-voight-kampff Closed Feb 27, 2026

Description

When running Claude Code in headless mode with --permission-mode bypassPermissions, the tool_use_id field is missing from PreToolUse and PostToolUse hook payloads. This field is documented as a standard field and is present in interactive mode.

Steps to Reproduce

  1. Configure a hook in .claude/settings.json:
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "/path/to/hook.sh",
        "timeout": 5
      }]
    }]
  }
}
  1. Run Claude Code in headless mode:
claude -p "List files in current directory" --permission-mode bypassPermissions
  1. Observe the hook payload - tool_use_id is missing

Expected Behavior

Hook payload should include tool_use_id as documented:

{
  "session_id": "abc123-...",
  "tool_use_id": "toolu_01ABC123...",
  "tool_name": "Bash",
  "tool_input": {...}
}

Actual Behavior

In headless/bypassPermissions mode, tool_use_id is missing:

{
  "session_id": "abc123-...",
  "tool_name": "Bash",
  "tool_input": {...}
}

Note: In interactive mode, tool_use_id IS correctly included (e.g., "toolu_015kC3i7UPieqAdSvNaXFGda").

Impact

This breaks correlation between PreToolUse and PostToolUse events for telemetry/observability systems that rely on tool_use_id to match tool start/end events.

Workaround

Generate a UUID server-side if missing, and correlate PostToolUse with PreToolUse by matching session_id + tool_name + finding the most recent unfinished tool call.

Environment

  • Claude Code version: Latest (as of Jan 2026)
  • OS: macOS
  • Permission mode: bypassPermissions

View original on GitHub ↗

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