Skip to content

sbx run doesn't relay agent output without a TTY, so every iteration is a silent no-op on Git Bash #6

Description

@tjdrabek

Running on Windows under Git Bash, every iteration finishes instantly and does nothing. Banner prints, sandbox starts, Iteration 1 of N prints, then an empty Iteration Summary and the sandbox stops. .agent/logs/LOG.md never gets touched, no task ever gets picked up.

This is the same thing as #3, which got closed with "Needed to run from home terminal, not inside of sandbox." I dug into it a bit and I think the actual cause is narrower than that, and fixable in Ralph.

The agent isn't idle, Ralph just can't see it. I counted Claude session files inside the container before and after an iteration and the count goes up every time, so sbx run is starting the agent and forwarding the -- AGENT_ARGS fine. The problem is that sbx run opens an interactive session and only relays the container's PTY stream to a real TTY. Without one it exits 0 having written nothing to stdout.

Since that captured text is the only thing Ralph uses to decide whether work happened, everything downstream falls over quietly: extract_final_summary finds no "type":"result", the tail -n 10 fallback picks up only sbx's own banner lines, no <promise> tag matches, and the iteration gets marked complete. Nothing looks at git, tasks.json, or the child's exit code, so an empty capture and a successful run are the same thing as far as Ralph is concerned.

Same sandbox, same agent args, stdout not a TTY:

# what Ralph does today: exit 0, zero agent output
sbx run --name <sandbox> -- --output-format stream-json --verbose -p "Reply with exactly OK"

# sbx exec instead: full stream comes back
sbx exec <sandbox> -- claude --output-format stream-json --verbose -p "Reply with exactly OK"
{"type":"system","subtype":"init",...}
{"type":"assistant","message":{...,"content":[{"type":"text","text":"OK"}]},...}
{"type":"result","result":"OK",...}

So auth, model access and --output-format stream-json are all fine, it's only the relay.

As for why there's no TTY: ralph.sh:163 wraps the command in script purely to get a pty, but Git for Windows doesn't ship util-linux, so script doesn't exist. It fails with 127 and captures nothing. And since script's own stderr is sent to /dev/null there, you get no hint that any of this happened.

What worked for me was switching the attach path to sbx exec, which is the batch form, writes straight to a pipe and starts the sandbox if it's stopped:

sbx exec <name> -- <agent> <existing agent args>

In build_agent_command that just means the separator becomes -- <agent> instead of a bare --; each agent's existing argument tail stays as-is. For the create path, sbx create --name <name> <agent> . then sbx exec avoids the interactive attach. Once you're on sbx exec the script wrapper isn't needed at all and can be a plain redirect:

bash -c "$AGENT_COMMAND" > "$OUTPUT_FILE" 2>&1 &

I've been running that locally for a while now and it's been fine, preview shows live tool calls and iterations actually pick up and finish tasks.

Couple of smaller things I noticed while in there. An iteration that captures zero bytes probably shouldn't count as a success regardless of the cause, so some kind of guard after OUTPUT= is assigned would turn this class of failure into something visible instead of silent. And ralph.sh:198 does wait "$AGENT_PID" || true, which throws away the child's exit status. That matters more than it sounds, because attaching to a cold sandbox can fail on its own: I got ERROR: agent exited with code 1 on a first attach to a stopped sandbox, then exit 0 from a warm rerun of the exact same command. Ralph stops the sandbox after every run, so every invocation is attaching cold.

One thing that is not the cause, in case it comes up: the sbx run <name> deprecation warning is a red herring. On sbx v0.38.0 the legacy positional form still starts the sandbox, still forwards the args and still runs the agent. Using sbx run --name <name> silences the warning and gives you exactly the same empty output. Probably still worth updating in agents.sh since the compat path won't be there forever. I also checked and ruled out CRLF line endings (everything's LF), missing prompt/task files, sandbox auth, MSYS path mangling and an empty $PROMPT_CONTENT.

Env: Windows 11, Git Bash (mintty), sbx v0.38.0, @pageai/ralph-loop@2.7.0, agent claude.

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