You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
🤖 fix: use stdin.abort() to prevent hangs on SSH commands (#504)
## Problem
Commands like `cat /tmp/results.json | jq '.'` would sometimes hang
forever over SSH, not respecting timeouts. This was observed over SSH
with the bash tool, and it's unclear if it happens on local workspaces.
## Root Cause
The issue stems from using `WritableStream.close()` to close stdin:
- **`close()` is async** and waits for graceful acknowledgment from the
remote end
- Over SSH with ControlMaster multiplexing, the SSH channel's stdin
buffer might not be immediately flushed
- The `close()` promise waits for acknowledgment that may never come
- Even timeouts couldn't help because the promise was already stuck in
Node.js stream machinery
## Solution
**Use `stdin.abort()` instead of `stdin.close()` for immediate
closure:**
- **`abort()`** - Immediate, synchronous force-close. Marks stream as
errored, releases locks, doesn't wait
- **`close()`** - Graceful, async close. Waits for all writes to be
acknowledged
Applied selectively:
- **bash tool**: Use `abort()` - commands don't need stdin at all
- **SSHRuntime mv/rm/stat**: Use `abort()` - commands don't read stdin
- **SSHRuntime writeFile**: Keep `close()` - needs to flush data written
to stdin
## Testing
- All 45 bash tool tests pass
- SSH integration tests pass:
- `runtimeExecuteBash` - verifies bash commands over SSH work
- `renameWorkspace` - verifies mv operations work
- `runtimeFileEditing` - verifies file writes (which use stdin) work
correctly
- All 921 unit tests pass
- Typecheck passes
## Implementation Details
Changed 4 locations:
1. `src/services/tools/bash.ts` - Use `abort()` to close stdin
immediately
2. `src/runtime/SSHRuntime.ts` (3 places) - Use `abort()` for mv/rm/stat
commands
Kept `close()` in 1 location:
- `SSHRuntime.writeFile()` - Needs graceful close to ensure all data is
written
---
_Generated with `cmux`_
0 commit comments