[BUG] PreToolUse Hook Causes TUI Rendering Corruption

Resolved 💬 5 comments Opened Nov 29, 2025 by JUN-PRODUCE Closed Feb 4, 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?

Using PreToolUse hook as guardrail for all tools (no matcher specified) to block operations based on keyword detection.

Symptoms:

  • TUI rendering corruption occurs regardless of hook output format
  • Text overlapping with previous output
  • Layout corruption in TUI
  • Inconsistent line breaks/spacing

Tested scenarios (all produce identical corruption):

  • Simple string: echo "BLOCK: Test" >&2
  • Official JSON format: echo '{"hookSpecificOutput": ...}' >&2
  • Multi-line heredoc
  • Empty output: exit 0 only (no echo)
  • Different tools: Bash/Read/Write

Reproduction rate: 100%

Related to Issue #9661 (PreToolUse hook displayed instead of actual tool invocation) - still OPEN in v2.0.55

What Should Happen?

Hook output should display cleanly in TUI with proper formatting:

BLOCK: Test

Expected behavior:

  • No text overlapping
  • Proper cursor positioning
  • Readable, well-formatted output

Error Messages/Logs

PreToolUse:Bash hook error: [bash .claude/hook_test.sh]: BLOCK: Test


*(Renders with visual corruption in TUI)*

Note: This occurs even with minimal hook script (exit 0 only, no output).

Steps to Reproduce

  1. Create minimal hook script (.claude/hook_test.sh):

Simple string format:

#!/bin/bash
echo "BLOCK: Test" >&2
exit 2

Official JSON format (same corruption):

#!/bin/bash
echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "BLOCK: Test"}' >&2
exit 2
  1. Enable in .claude/settings.local.json:
"hooks": {
  "PreToolUse": [{"hooks": [{"type": "command", "command": "bash .claude/hook_test.sh"}]}]
}
  1. Execute any tool (Bash/Read/Write)
  2. Observe TUI display corruption

Reproduction rate: 100%

Workaround: None found. Disabling hooks is the only way to avoid corruption.

Claude Model

Sonnet (default)

Is this a regression?

Yes, this worked in a previous version

Last Working Version

Probably around 2.0.52

Claude Code Version

2.0.55

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Environment:

  • Claude Code Version: 2.0.55
  • Platform: Anthropic API
  • OS: Windows (NT 10.0-19044)
  • Model: Sonnet

Video recordings attached showing:

  • Hook enabled: corruption visible
  • Hook disabled: normal display

Related issues:

  • #9661: PreToolUse hook displayed instead of actual tool invocation (reported v2.0.15, claimed fixed v2.0.19, still occurs v2.0.55)
  • #5557: Startup hook output re-displays on every turn with --verbose

Hook pattern used:

echo '{"hookSpecificOutput": {"permissionDecision": "deny"}, "systemMessage": "reason"}' >&2
exit 2

(Based on official examples from anthropics/claude-code repository)

https://github.com/user-attachments/assets/dc10d45e-1582-4a75-ad6b-41608a866490
https://github.com/user-attachments/assets/7624baef-d4e5-459f-b351-269ef02060da

View original on GitHub ↗

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