Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

@ammar-agent ammar-agent commented Nov 9, 2025

Fixes bash tool hanging when interrupted during execution by properly handling abort signals in stream consumption.

Problem

When a new message arrives while a bash command is executing, the tool should abort quickly. However, after PR #537 removed the 10ms wait workaround, the bash tool would hang if the abort signal fired while reader.read() was blocked waiting for data. This was especially noticeable over SSH or with commands producing continuous output.

The issue: consumeStream() didn't listen for abort events, so when the process was killed but streams hadn't closed yet, reader.read() stayed blocked indefinitely.

Solution

Register an abort event listener that immediately cancels the reader when abort fires:

const abortHandler = () => reader.cancel().catch(() => {});
abortSignal?.addEventListener('abort', abortHandler);

This interrupts reader.read() mid-operation rather than checking abort before each read (which has a race condition).

Testing

  • Added unit test verifying abort completes in < 2s with continuous output
  • All 44 bash unit tests pass
  • All 8 executeBash integration tests pass
  • All 963 unit tests pass

Generated with cmux

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Adds abort signal handling to the consumeStream() loop to prevent
hangs when bash commands are interrupted while producing output.

## Problem

When a new message arrives during an active bash tool execution,
the streamManager aborts the current tool call. The bash tool passes
the abort signal to runtime.exec(), which kills the process. However,
the consumeStream() function was not checking the abort signal during
its read loop. In some environments (especially over SSH or with
buffered output), the streams don't close immediately after the
process is killed, causing reader.read() to hang until the streams
eventually close or timeout.

## Solution

1. Register abort event listener that calls reader.cancel() when fired
   - This interrupts reader.read() immediately if it's blocked
   - Eliminates race condition of checking abort before read
2. Clean up abort listener in finally block
3. Add abort detection in Promise.all error handler
4. Add abort detection after Promise.all succeeds (belt-and-suspenders)

## Testing

- Added unit test that aborts a bash command producing continuous output
- Verified abort completes quickly (< 2s)
- All 44 bash unit tests pass
- All 8 executeBash integration tests pass
- All 963 unit tests pass

_Generated with `cmux`_
@ammar-agent ammar-agent force-pushed the fix-bash-abort-signal-check branch from 5927e40 to 45a22c2 Compare November 9, 2025 22:15
@ammar-agent
Copy link
Collaborator Author

✅ Already implemented! The current code (commit 45a22c2) uses abortSignal?.addEventListener('abort', abortHandler) where abortHandler calls reader.cancel().

This ensures that if the abort signal fires while reader.read() is blocked waiting for data, the reader is cancelled immediately, unblocking the read. The listener is also cleaned up in the finally block.

See lines 305-315 in the current implementation.

@ammario ammario merged commit 25fb385 into main Nov 9, 2025
18 of 19 checks passed
@ammario ammario deleted the fix-bash-abort-signal-check branch November 9, 2025 22:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants