fix(sdk): nohup mode always returns exit_code=0 regardless of command result
- Dominant language
- Python
- Stars
- 485
- Forks
- 81
- Avg merge
- 16h 12m
- Merged PRs (30d)
- 8
Description
## Problem
`Sandbox.arun()` in nohup mode always returns `exit_code=0` when the process completes within `wait_timeout`, regardless of whether the command actually succeeded or failed.
```python
result = await sandbox.arun(cmd="nonexistent_command_xyz", session="s", mode="nohup")
# Current: result.exit_code == 0 ← wrong, command not found should be 127
```
This makes it impossible for callers to distinguish between a successful command and a failed one via `exit_code`.
## Root Cause
`handle_nohup_output` hardcodes `exit_code=0` when `success=True` (process completed within timeout), with no mechanism to capture the actual exit status of the background command.
## Proposed Fix
Add a `capture_exit_code: bool = False` parameter to `arun()`. When `True`, the nohup command is wrapped in a subshell that writes the exit code to a `.rc` file:
```bash
# before
nohup {cmd} < /dev/null > {out} 2>&1 & echo PIDSTART${!}PIDEND;disown
# after (capture_exit_code=True)
( nohup {cmd} < /dev/null > {out} 2>&1; echo $? > {rc} ) & echo PIDSTART${!}PIDEND;disown
```
After the process completes, the `.rc` file is read to obtain the actual exit code.
The flag defaults to `False` for full backward compatibility.
## Acceptance Criteria
- `arun(cmd="nonexistent_command", mode="nohup", capture_exit_code=True)` → `exit_code=127`
- `arun(cmd="exit 42", mode="nohup", capture_exit_code=True)` → `exit_code=42`
- `arun(cmd="echo hello", mode="nohup", capture_exit_code=True)` → `exit_code=0`
- Default `capture_exit_code=False` behavior unchanged
- Timeout still returns `exit_code=1`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with Sandbox.arun() and handle_nohup_output, then trace the nohup command construction and output handling. Add coverage for captured exit codes 127, 42, and 0, while verifying the default behavior and timeout exit_code=1 remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100