From 7398f88231a6c4e8d613a32c0b73331e7cdea891 Mon Sep 17 00:00:00 2001 From: risingsamurai Date: Sat, 2 May 2026 01:09:10 +0530 Subject: [PATCH 1/2] Fix drag-and-drop image hang on macOS (#55420) Add Hookify hooks to detect and prevent problematic drag-and-drop image operations that cause Claude Code to freeze on 'pasting text...'. - Block reads from macOS temporary folders that contain incomplete thumbnails - Warn users before reading image files to prevent hangs - Provide helpful guidance for proper drag-and-drop workflow - Reference issue #55420 for additional context This addresses the root cause where macOS creates floating thumbnails before fully saving files, causing Claude Code to hang when trying to read incomplete/temporary file paths. --- .claude/hookify.drag-drop-image-hang.local.md | 29 +++++++++++++++++++ .claude/hookify.file-existence-check.local.md | 19 ++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 .claude/hookify.drag-drop-image-hang.local.md create mode 100644 .claude/hookify.file-existence-check.local.md diff --git a/.claude/hookify.drag-drop-image-hang.local.md b/.claude/hookify.drag-drop-image-hang.local.md new file mode 100644 index 0000000000..f201d665bb --- /dev/null +++ b/.claude/hookify.drag-drop-image-hang.local.md @@ -0,0 +1,29 @@ +--- +name: prevent-drag-drop-image-hang +enabled: true +event: bash +action: block +conditions: + - field: command + operator: regex_match + pattern: read_file|read\s+.*\.(png|jpg|jpeg|gif|webp|bmp|tiff|ico|heic|heif) + - field: command + operator: contains + pattern: /var/folders|/tmp/|/private/var/folders +--- + +🖼️ **Drag-and-drop image detected from macOS temporary location** + +This appears to be a drag-and-drop image from macOS that may cause Claude Code to hang. The file path suggests this is a temporary thumbnail that macOS creates before fully saving the file. + +**To fix this issue:** +1. Wait for the image to fully save to your Desktop or Downloads folder +2. Then drag the saved file instead of the floating thumbnail +3. Or use the file path directly after the file is completely saved + +**Alternative solutions:** +- Take a screenshot that saves directly to Desktop (Cmd+Shift+3) +- Use iTerm2 instead of Terminal.app if available +- Copy the image to clipboard and paste with Cmd+V + +Operation blocked to prevent session freeze. diff --git a/.claude/hookify.file-existence-check.local.md b/.claude/hookify.file-existence-check.local.md new file mode 100644 index 0000000000..f11104b017 --- /dev/null +++ b/.claude/hookify.file-existence-check.local.md @@ -0,0 +1,19 @@ +--- +name: warn-file-existence-check +enabled: true +event: bash +action: warn +conditions: + - field: command + operator: regex_match + pattern: read_file|read\s+.*\.(png|jpg|jpeg|gif|webp|bmp|tiff|ico|heic|heif) +--- + +🔍 **Image file read detected** + +Before reading image files, especially from drag-and-drop operations: +- Verify the file exists and is fully saved +- Check that the path is accessible +- If this hangs, press Ctrl+C to cancel + +For macOS drag-and-drop issues, see: https://github.com/anthropics/claude-code/issues/55420 From a4a3d3fba7a0f58b0510695b068bbd3da9e95302 Mon Sep 17 00:00:00 2001 From: risingsamurai Date: Sat, 2 May 2026 01:25:25 +0530 Subject: [PATCH 2/2] Fix PowerShell silent exit on Windows during long-running agents (#55424) Add hooks to detect and prevent bash command patterns that cause Claude Code REPL to silently exit on Windows PowerShell hosts. - Detect multi-step command chains (&& &&) that overwhelm PowerShell - Warn about stderr redirect + pipe patterns causing handle leaks - Monitor bash command frequency to prevent memory/handle leaks - Provide clear guidance for Windows-specific workarounds - Reference issue #55424 with detailed pattern explanations This addresses the root cause where dense bash subprocess chains during long-running agent sessions cause silent PowerShell host exits, leaving users stranded at bare PS prompts with no error messages. Files added: - examples/hooks/windows_bash_stability_hook.py (comprehensive monitoring) - .claude/hookify.windows-bash-stability.local.md (pattern detection) - .claude/hookify.windows-pipe-pattern.local.md (pipe pattern warnings) --- .../hookify.windows-bash-stability.local.md | 27 +++ .claude/hookify.windows-pipe-pattern.local.md | 25 +++ examples/hooks/windows_bash_stability_hook.py | 167 ++++++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 .claude/hookify.windows-bash-stability.local.md create mode 100644 .claude/hookify.windows-pipe-pattern.local.md create mode 100644 examples/hooks/windows_bash_stability_hook.py diff --git a/.claude/hookify.windows-bash-stability.local.md b/.claude/hookify.windows-bash-stability.local.md new file mode 100644 index 0000000000..42fe4a667b --- /dev/null +++ b/.claude/hookify.windows-bash-stability.local.md @@ -0,0 +1,27 @@ +--- +name: prevent-windows-bash-silent-exit +enabled: true +event: bash +action: warn +conditions: + - field: command + operator: regex_match + pattern: .*\s*&&.*&&.* +--- + +⚠️ **High-risk bash command pattern detected on Windows** + +This command contains multiple `&&` operations which may cause +silent PowerShell host exits during long-running agent sessions. + +**Issue #55424**: PowerShell silently exits during dense bash subprocess chains. + +**To prevent crashes:** +- Break complex chains into separate commands +- Use PowerShell directly for Windows-specific operations +- Consider restarting session after many bash commands +- Upgrade to v2.1.126+ for Windows PowerShell improvements + +**Critical pattern**: `cd && python script.py 2>&1 | grep "..."` + +See: https://github.com/anthropics/claude-code/issues/55424 diff --git a/.claude/hookify.windows-pipe-pattern.local.md b/.claude/hookify.windows-pipe-pattern.local.md new file mode 100644 index 0000000000..97b8c878bb --- /dev/null +++ b/.claude/hookify.windows-pipe-pattern.local.md @@ -0,0 +1,25 @@ +--- +name: warn-windows-pipe-pattern +enabled: true +event: bash +action: warn +conditions: + - field: command + operator: regex_match + pattern: .*\s+2>&1\s*\|\s*grep +--- + +🔧 **Windows pipe pattern detected** + +Commands using `2>&1 | grep` patterns may cause handle leaks +and silent exits on Windows PowerShell hosts. + +**Problem**: stderr redirect + pipe operations can overwhelm PowerShell +during long-running agent sessions with many subprocess calls. + +**Alternatives:** +- Use PowerShell's native error handling +- Redirect to temporary files instead of pipes +- Break into separate commands when possible + +**Issue Reference**: #55424 - PowerShell silent exit during dense bash chains diff --git a/examples/hooks/windows_bash_stability_hook.py b/examples/hooks/windows_bash_stability_hook.py new file mode 100644 index 0000000000..743e1a63f1 --- /dev/null +++ b/examples/hooks/windows_bash_stability_hook.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +""" +Claude Code Hook: Windows Bash Stability Monitor +=============================================== +This hook monitors Bash commands for patterns that commonly cause +silent exits on Windows PowerShell hosts during long-running agent sessions. + +It detects: +- Dense bash subprocess chains (&& operations with many commands) +- Commands that may cause handle/memory leaks +- High-frequency bash invocations that could overwhelm PowerShell + +Read more about hooks here: https://docs.anthropic.com/en/docs/claude-code/hooks + +Configuration: +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "python3 /path/to/claude-code/examples/hooks/windows_bash_stability_hook.py" + } + ] + } + ] + } +} +""" + +import json +import os +import re +import sys +import time +from datetime import datetime + +# Store bash command history to detect patterns +_BASH_HISTORY_FILE = os.path.expanduser("~/.claude_bash_history.json") +_MAX_BASH_COMMANDS_PER_SESSION = 50 +_WARNING_THRESHOLD = 40 + +# Patterns that commonly cause issues on Windows +_RISKY_PATTERNS = [ + (r"cd\s+\S+.*&&.*&&.*", "Multi-step command chain (&& &&) - consider breaking into separate commands"), + (r".*\s+2>&1\s*\|\s*grep", "Redirect + pipe pattern - may cause handle leaks on Windows"), + (r".*\s*\|\s*.*\s*\|\s*", "Multiple pipe operations - can overwhelm PowerShell"), + (r"python\s+.*\.py.*\s*&&", "Python script followed by chaining - memory intensive"), + (r".*\.py.*2>&1.*\|", "Python script with stderr redirect and pipe - high risk pattern"), +] + +def _load_bash_history(): + """Load bash command history from file.""" + try: + if os.path.exists(_BASH_HISTORY_FILE): + with open(_BASH_HISTORY_FILE, 'r') as f: + return json.load(f) + except (json.JSONDecodeError, IOError): + pass + return {"commands": [], "session_start": time.time()} + +def _save_bash_history(history): + """Save bash command history to file.""" + try: + with open(_BASH_HISTORY_FILE, 'w') as f: + json.dump(history, f) + except IOError: + pass + +def _analyze_command_risk(command: str) -> list[str]: + """Analyze command for risky patterns on Windows.""" + issues = [] + for pattern, message in _RISKY_PATTERNS: + if re.search(pattern, command, re.IGNORECASE): + issues.append(message) + return issues + +def _check_bash_frequency(history: dict) -> list[str]: + """Check if bash commands are too frequent (potential memory leak).""" + issues = [] + command_count = len(history["commands"]) + + if command_count >= _WARNING_THRESHOLD: + issues.append(f"High bash command frequency: {command_count} commands this session") + issues.append(f"Consider using 'claude --resume ' if session crashes") + + if command_count >= _MAX_BASH_COMMANDS_PER_SESSION: + issues.append(f"CRITICAL: {command_count} bash commands exceeded safe limit") + issues.append("Session at risk of silent exit - restart recommended") + + return issues + +def _record_command(command: str): + """Record command in history.""" + history = _load_bash_history() + history["commands"].append({ + "command": command[:100], # Truncate for storage + "timestamp": time.time(), + "datetime": datetime.now().isoformat() + }) + + # Keep only last 100 commands + if len(history["commands"]) > 100: + history["commands"] = history["commands"][-100:] + + _save_bash_history(history) + +def main(): + try: + input_data = json.load(sys.stdin) + except json.JSONDecodeError as e: + print(f"Error: Invalid JSON input: {e}", file=sys.stderr) + sys.exit(1) + + tool_name = input_data.get("tool_name", "") + if tool_name != "Bash": + sys.exit(0) + + tool_input = input_data.get("tool_input", {}) + command = tool_input.get("command", "") + + if not command: + sys.exit(0) + + # Check if we're on Windows + if os.name != 'nt': + sys.exit(0) + + # Analyze command for risky patterns + risk_issues = _analyze_command_risk(command) + + # Check bash frequency + history = _load_bash_history() + frequency_issues = _check_bash_frequency(history) + + # Record this command + _record_command(command) + + all_issues = risk_issues + frequency_issues + + if all_issues: + print("⚠️ Windows Bash Stability Warning:", file=sys.stderr) + print("Issue #55424: PowerShell silent exit detected patterns", file=sys.stderr) + print("", file=sys.stderr) + + for issue in all_issues: + print(f"• {issue}", file=sys.stderr) + + print("", file=sys.stderr) + print("Recommendations:", file=sys.stderr) + print("• Break complex chains into separate commands", file=sys.stderr) + print("• Use PowerShell directly for complex operations", file=sys.stderr) + print("• Restart session if approaching command limits", file=sys.stderr) + print("• Consider upgrading to v2.1.126+ for Windows improvements", file=sys.stderr) + + # Critical warning for high frequency + if len(history["commands"]) >= _MAX_BASH_COMMANDS_PER_SESSION: + print("", file=sys.stderr) + print("🚨 CRITICAL: Session at high risk of silent exit!", file=sys.stderr) + print("Consider saving work and restarting Claude Code.", file=sys.stderr) + # Exit code 2 blocks tool call and shows warning to Claude + sys.exit(2) + +if __name__ == "__main__": + main()