Skip to content

fix(sdk): nohup mode always returns exit_code=0 regardless of command result #685

@Issac-Newton

Description

@Issac-Newton

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.

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:

# 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions