[BUG] plugin PostToolUse hook crashes Claude Code when interacting with long files

Resolved 💬 3 comments Opened Nov 12, 2025 by johnmatthewtennant Closed Jan 12, 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?

Minimal example. A plugin with this hook crashes claude code whenever it interacts with a long file.
The same hook does not trigger a crash when installed via settings.json

    "PostToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "true"
          }
        ]
      }
    ]
> try reading unified-server.ts 

I'll read the unified-server.ts file to understand the current server implementation.
Read(src/unified-server.ts)
Read(src/unified-server.ts)
  ⎿  Read 829 lines

~/Development/mcp-voice-hooks master 

What Should Happen?

claude should not crash

Error Messages/Logs

[DEBUG] Watching for changes in setting files /Users/jtennant/.claude/settings.json, /Users/jtennant/Development/mcp-voice-hooks/.claude/settings.json, /Users/jtennant/Development/mcp-voice-hooks/.claude/settings.local.json...
[DEBUG] [LSP MANAGER] initializeLspServerManager() called
[DEBUG] [LSP MANAGER] Created manager instance, state=pending
[DEBUG] [LSP MANAGER] Starting async initialization (generation 1)
[DEBUG] [LSP SERVER MANAGER] initialize() called
[DEBUG] [LSP SERVER MANAGER] Calling getAllLspServers()
[DEBUG] Applying permission update: Adding 22 allow rule(s) to destination 'localSettings': ["WebFetch(domain:docs.anthropic.com)","WebFetch(domain:modelcontextprotocol.io)","Bash(npm install:*)","Bash(mkdir:*)","Bash(git add:*)","Bash(git commit:*)","Bash(npm run build:*)","Bash(npm run:*)","mcp__voice-hooks__get_recent_utterances","Bash(npm test)","Bash(npm test:*)","Bash(curl:*)","Bash(grep:*)","mcp__voice-hooks__dequeue_utterances","mcp__voice-hooks__wait_for_utterance","Bash(./stop-hook.sh:*)","Bash(ls:*)","mcp__voice-hooks__speak","mcp__voice-hooks__speak_and_then_wait_for_utterance","mcp__plugin_mcp-voice-hooks_voice-hooks__speak","mcp__plugin_mcp-voice-hooks-dev-plugin_voice-hooks__speak","Bash(lsof:*)"]
[DEBUG] Loading plugin mcp-voice-hooks-plugin from source: "./plugin"
[DEBUG] Loaded hooks from standard location for plugin mcp-voice-hooks-plugin: /Users/jtennant/.claude/plugins/marketplaces/mcp-voice-hooks-marketplace/plugin/hooks/hooks.json
[DEBUG] Loading plugin mcp-voice-hooks-dev-plugin from source: "./dev-plugin"
[DEBUG] Loaded hooks from standard location for plugin mcp-voice-hooks-dev-plugin: /Users/jtennant/Development/mcp-voice-hooks/dev-marketplace/dev-plugin/hooks/hooks.json
[DEBUG] Found 2 plugins (1 enabled, 1 disabled)
[DEBUG] Loading skills from directories: managed=/Library/Application Support/ClaudeCode/.claude/skills, user=/Users/jtennant/.claude/skills, project=/Users/jtennant/Development/mcp-voice-hooks/.claude/skills
[DEBUG] >>>>> getPluginSkills CALLED <<<<<
[DEBUG] Creating shell snapshot for zsh (/bin/zsh)
[DEBUG] Looking for shell config file: /Users/jtennant/.zshrc
[DEBUG] Snapshots directory: /Users/jtennant/.claude/shell-snapshots
[DEBUG] Creating snapshot at: /Users/jtennant/.claude/shell-snapshots/snapshot-zsh-1762978089013-avh8l3.sh
[DEBUG] Shell binary exists: true
[DEBUG] Execution timeout: 10000ms
[DEBUG] Writing to temp file: /Users/jtennant/.claude/todos/547892f7-b358-4003-94c7-fe0d91b310e8-agent-547892f7-b358-4003-94c7-fe0d91b310e8.json.tmp.92691.1762978089015
[DEBUG] Temp file written successfully, size: 2 bytes
[DEBUG] Renaming /Users/jtennant/.claude/todos/547892f7-b358-4003-94c7-fe0d91b310e8-agent-547892f7-b358-4003-94c7-fe0d91b310e8.json.tmp.92691.1762978089015 to /Users/jtennant/.claude/todos/547892f7-b358-4003-94c7-fe0d91b310e8-agent-547892f7-b358-4003-94c7-fe0d91b310e8.json
[DEBUG] File /Users/jtennant/.claude/todos/547892f7-b358-4003-94c7-fe0d91b310e8-agent-547892f7-b358-4003-94c7-fe0d91b310e8.json written atomically
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089032
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67373 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089032 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] getPluginSkills: Processing 1 enabled plugins
[DEBUG] Checking plugin mcp-voice-hooks-dev-plugin: skillsPath=none, skillsPaths=0 paths
[DEBUG] Total plugin skills loaded: 0
[DEBUG] Total plugin commands loaded: 0
[DEBUG] Loading hooks from plugin: mcp-voice-hooks-dev-plugin
[DEBUG] Registered 4 hooks from 1 plugins
[DEBUG] Loaded 3 unique skills (managed: 0, user: 3, project: 0, duplicates removed: 0)
[DEBUG] getSkillsIfEnabled returning: 3 skill dir commands, 0 plugin skills
[DEBUG] Total LSP servers loaded: 0
[DEBUG] [LSP SERVER MANAGER] getAllLspServers returned 0 server(s)
[DEBUG] LSP manager initialized with 0 servers
[DEBUG] LSP server manager initialized successfully
[DEBUG] LSP notification handlers registered successfully for all 0 server(s)
[DEBUG] Ripgrep first use test: PASSED (mode=builtin, path=/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/vendor/ripgrep/arm64-darwin/rg)
[DEBUG] Total plugin agents loaded: 0
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089159
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67373 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089159 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] Getting matching hook commands for SessionStart with query: startup
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "startup" (0 before deduplication)
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089236
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67268 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089236 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089245
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67268 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089245 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] AutoUpdaterWrapper: Installation type: npm-global
[DEBUG] performStartupChecks called
[DEBUG] Starting background plugin installations
[DEBUG] performBackgroundPluginInstallations called
[DEBUG] LSP Diagnostics: getLSPDiagnosticAttachments called
[DEBUG] LSP Diagnostics: Checking registry - 0 pending
[DEBUG] LSP Diagnostics: Returning 0 diagnostic set(s) for delivery
[DEBUG] Hooks: getAsyncHookResponseAttachments called
[DEBUG] Hooks: checkForNewResponses called
[DEBUG] Hooks: Found 0 total hooks in registry
[DEBUG] Hooks: checkForNewResponses returning 0 responses
[DEBUG] Found 2 extra marketplaces in settings
[DEBUG] Loaded plugins - Enabled: 1, Disabled: 1, Commands: 0, Agents: 0, Errors: 0
[DEBUG] Found 1 enabled plugins
[DEBUG] Schema version mismatch (current: 0, expected: 1), syncing installed_plugins.json
[DEBUG] Loaded 2 installed plugins from /Users/jtennant/.claude/plugins/installed_plugins.json (schema version 1)
[DEBUG] Plugin mcp-voice-hooks-plugin@mcp-voice-hooks-marketplace already in installed_plugins.json, skipping
[DEBUG] Plugin mcp-voice-hooks-dev-plugin@mcp-voice-hooks-dev-marketplace already in installed_plugins.json, skipping
[DEBUG] Saved 2 installed plugins to /Users/jtennant/.claude/plugins/installed_plugins.json (schema version 1)
[DEBUG] Updated installed_plugins.json to schema version 1 (0 plugins added, 2 skipped)
[DEBUG] Found 2 installed plugins
[DEBUG] Found 0 missing plugins (not installed):
[DEBUG] Setting installation status: 0 marketplaces, 0 installable plugins, 0 uninstallable plugins
[DEBUG] Getting matching hook commands for UserPromptSubmit with query: undefined
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "no match query" (0 before deduplication)
[DEBUG] MCP server "ide": Starting connection with timeout of 30000ms
[DEBUG] FileHistory: Added snapshot for 34082236-3afb-4211-9510-515404bd64ea, tracking 0 files
[DEBUG] Slash commands included in SlashCommand tool: /update-tests, /remove-feature-flag, /update-feature-flag-documentation, /trace-code-origin, /update-tests, /remove-feature-flag, /update-feature-flag-documentation, /trace-code-origin
[DEBUG] Skills and commands included in Skill tool: when-your-bash-command-contains-any-pipes-use-backticks-for-comm, update-your-memory-by-creating-or-updating-an-ai-rules-ai-rule-m, use-github-permalinks-for-code-references
[DEBUG] Summarizing all 4 messages (~0 tokens)
[DEBUG] MCP server "ide": Successfully connected to ws-ide server in 57ms
[DEBUG] MCP server "ide": Connection established with capabilities: {"hasTools":true,"hasPrompts":false,"hasResources":false,"serverVersion":{"name":"Claude Code Cursor MCP","version":"2.0.37"}}
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089791
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67268 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089791 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089802
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67268 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089802 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978089812
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67373 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978089812 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically
[DEBUG] Skills and commands included in Skill tool: when-your-bash-command-contains-any-pipes-use-backticks-for-comm, update-your-memory-by-creating-or-updating-an-ai-rules-ai-rule-m, use-github-permalinks-for-code-references
[DEBUG] Slash commands included in SlashCommand tool: /update-tests, /remove-feature-flag, /update-feature-flag-documentation, /trace-code-origin, /update-tests, /remove-feature-flag, /update-feature-flag-documentation, /trace-code-origin
[DEBUG] Shell snapshot created successfully (161688 bytes)
[DEBUG] Stream started - received first chunk
[DEBUG] Stream started - received first chunk
[DEBUG] Stream started - received first chunk
[DEBUG] Summarizing all 4 messages (~0 tokens)
[DEBUG] Stream started - received first chunk
[DEBUG] Stream started - received first chunk
[DEBUG] Stream started - received first chunk
[DEBUG] Summarizing all 6 messages (~4090 tokens)
[DEBUG] executePreToolHooks called for tool: Read
[DEBUG] Getting matching hook commands for PreToolUse with query: Read
[DEBUG] Found 2 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "Read" (0 before deduplication)
[DEBUG] Getting matching hook commands for PostToolUse with query: Read
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 unique hooks for query "Read" (1 before deduplication)
[DEBUG] LSP Diagnostics: getLSPDiagnosticAttachments called
[DEBUG] LSP Diagnostics: Checking registry - 0 pending
[DEBUG] LSP Diagnostics: Returning 0 diagnostic set(s) for delivery
[DEBUG] Hooks: getAsyncHookResponseAttachments called
[DEBUG] Hooks: checkForNewResponses called
[DEBUG] Hooks: Found 0 total hooks in registry
[DEBUG] Hooks: checkForNewResponses returning 0 responses
[DEBUG] Skills and commands included in Skill tool: when-your-bash-command-contains-any-pipes-use-backticks-for-comm, update-your-memory-by-creating-or-updating-an-ai-rules-ai-rule-m, use-github-permalinks-for-code-references
[DEBUG] Slash commands included in SlashCommand tool: /update-tests, /remove-feature-flag, /update-feature-flag-documentation, /trace-code-origin, /update-tests, /remove-feature-flag, /update-feature-flag-documentation, /trace-code-origin
[DEBUG] Getting matching hook commands for SubagentStop with query: undefined
[DEBUG] Found 0 hook matchers in settings
[DEBUG] Matched 0 unique hooks for query "no match query" (0 before deduplication)
[DEBUG] Writing to temp file: /Users/jtennant/.claude.json.tmp.92691.1762978093787
[DEBUG] Preserving file permissions: 100644
[DEBUG] Temp file written successfully, size: 67775 bytes
[DEBUG] Applied original permissions to temp file
[DEBUG] Renaming /Users/jtennant/.claude.json.tmp.92691.1762978093787 to /Users/jtennant/.claude.json
[DEBUG] File /Users/jtennant/.claude.json written atomically

Steps to Reproduce

create a plugin with a hook in the default location:

    "PostToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "true"
          }
        ]
      }
    ]

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.0.37

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

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