[GH-ISSUE #150] [Bug]: ralph run hangs and does nothing #59

Closed
opened 2026-02-27 10:21:59 +03:00 by kerem · 4 comments
Owner

Originally created by @The-Zona-Zoo on GitHub (Feb 3, 2026).
Original GitHub issue: https://github.com/mikeyobrien/ralph-orchestrator/issues/150

Operating system

Windows 11

Ralph version

2.4.3

AI backend

Claude Code

Hat preset / workflow

spec-driven

Steps to reproduce

  1. ralph installed via cargo (unable to install with npm on windows)
  2. ralph init --preset spec-driven
  3. ralph run (PROMPT.MD exists after running ralph plan)
  4. TUI opens, loop never starts executing
  5. Eventually I ctrl+C to quit. It doesn't matter how long I wait, the logs never progress any further.

Expected behavior

ralph loop to run as expected

Actual behavior

ralph hangs on iteration 1/X without every calling the backend model

Logs or error output

2026-02-03T06:21:01.941301Z DEBUG ralph_core::config: Loading configuration from file path=ralph.yml
2026-02-03T06:21:01.941531Z DEBUG ralph_core::config: Configuration loaded backend=claude has_v1_fields=false custom_hats=4
2026-02-03T06:21:01.941570Z  INFO ralph: Creating scratchpad directory: <REPO_PATH>\.ralph/agent
2026-02-03T06:21:01.941831Z  WARN ralph: Loop locking not supported on this platform, running without lock
2026-02-03T06:21:01.941984Z DEBUG ralph::loop_runner: Resolving prompt content inline_prompt=None prompt_file=PROMPT.md
2026-02-03T06:21:01.942009Z DEBUG ralph::loop_runner: Checking prompt file path=PROMPT.md exists=true
2026-02-03T06:21:01.942050Z DEBUG ralph::loop_runner: Read prompt from file path=PROMPT.md len=2731
2026-02-03T06:21:01.942313Z DEBUG ralph::loop_runner: Wrote loop ID marker file loop_id=primary-20260203-062101 marker="<REPO_PATH>\\.ralph\\current-loop-id"
2026-02-03T06:21:01.942556Z DEBUG ralph::loop_runner: Created events file for this run: .ralph/events-20260203-062101.jsonl
2026-02-03T06:21:01.942636Z DEBUG ralph_core::event_loop: Multi-hat mode: 4 custom hats + Ralph as fallback
2026-02-03T06:21:01.942793Z DEBUG ralph_core::event_loop: Published spec.start event topic="spec.start"
2026-02-03T06:21:01.942997Z DEBUG ralph_core::event_logger: Event logged topic=spec.start iteration=0
2026-02-03T06:21:02.056757Z DEBUG ralph::loop_runner: Execution mode configured execution_mode=autonomous
2026-02-03T06:21:02.057313Z  WARN ralph::loop_runner: Failed to record loop start in history: I/O error: File locking not supported on this platform
2026-02-03T06:21:02.057354Z DEBUG ralph::loop_runner: Iteration 1/100 - ralph active
2026-02-03T06:21:02.057453Z DEBUG ralph_core::event_loop: build_prompt: routing to HatlessRalph (multi-hat coordinator mode), active_hats: ["spec_writer"]
2026-02-03T06:21:02.057472Z  INFO ralph_core::event_loop: Memory injection check: enabled=true, inject=Auto, workspace_root="<REPO_PATH>"
2026-02-03T06:21:02.057481Z  INFO ralph_core::event_loop: Looking for memories at: "<REPO_PATH>\\.ralph/agent/memories.md" (exists: false)
2026-02-03T06:21:02.058599Z  INFO ralph_core::event_loop: Successfully loaded 0 memories from store
2026-02-03T06:21:02.058609Z  INFO ralph_core::event_loop: Memory store is empty - no memories to inject
2026-02-03T06:21:02.058622Z DEBUG ralph_core::event_loop: Injected ralph-tools skill from registry
2026-02-03T06:21:02.058796Z DEBUG ralph_core::event_loop: Scratchpad not found at "<REPO_PATH>\\.ralph\\agent\\scratchpad.md", skipping injection
2026-02-03T06:21:02.061378Z DEBUG ralph::loop_runner: Using global backend for 'spec_writer': claude
2026-02-03T06:21:02.066745Z DEBUG ralph_adapters::cli_backend: Built CLI command command=claude args_count=7 prompt_len=16960 interactive=false uses_stdin=false uses_temp_file=true
2026-02-03T06:21:02.267857Z DEBUG ralph_adapters::pty_executor: Spawning PTY output reader thread (streaming mode)
2026-02-03T06:21:55.043368Z  INFO ralph_tui::app: Ctrl+C detected, signaling main loop
2026-02-03T06:21:55.043832Z  INFO ralph_core::event_loop: Wrapping up: interrupted. 0 iterations in 53s. reason=interrupted iterations=0 duration=53s
2026-02-03T06:21:55.043866Z DEBUG ralph_core::event_logger: Event logged topic=loop.terminate iteration=0
2026-02-03T06:21:55.070403Z  WARN ralph::loop_runner: Failed to record termination in history: I/O error: File locking not supported on this platform
2026-02-03T06:21:55.070417Z  WARN ralph::loop_runner: Failed to deregister loop from registry: File locking not supported on this platform

Config / preset file

spec-driven

Originally created by @The-Zona-Zoo on GitHub (Feb 3, 2026). Original GitHub issue: https://github.com/mikeyobrien/ralph-orchestrator/issues/150 ### Operating system Windows 11 ### Ralph version 2.4.3 ### AI backend Claude Code ### Hat preset / workflow spec-driven ### Steps to reproduce 1. ralph installed via cargo (unable to install with npm on windows) 2. `ralph init --preset spec-driven` 3. `ralph run` (PROMPT.MD exists after running `ralph plan`) 4. TUI opens, loop never starts executing 5. Eventually I ctrl+C to quit. It doesn't matter how long I wait, the logs never progress any further. ### Expected behavior ralph loop to run as expected ### Actual behavior ralph hangs on iteration 1/X without every calling the backend model ### Logs or error output ```shell 2026-02-03T06:21:01.941301Z DEBUG ralph_core::config: Loading configuration from file path=ralph.yml 2026-02-03T06:21:01.941531Z DEBUG ralph_core::config: Configuration loaded backend=claude has_v1_fields=false custom_hats=4 2026-02-03T06:21:01.941570Z INFO ralph: Creating scratchpad directory: <REPO_PATH>\.ralph/agent 2026-02-03T06:21:01.941831Z WARN ralph: Loop locking not supported on this platform, running without lock 2026-02-03T06:21:01.941984Z DEBUG ralph::loop_runner: Resolving prompt content inline_prompt=None prompt_file=PROMPT.md 2026-02-03T06:21:01.942009Z DEBUG ralph::loop_runner: Checking prompt file path=PROMPT.md exists=true 2026-02-03T06:21:01.942050Z DEBUG ralph::loop_runner: Read prompt from file path=PROMPT.md len=2731 2026-02-03T06:21:01.942313Z DEBUG ralph::loop_runner: Wrote loop ID marker file loop_id=primary-20260203-062101 marker="<REPO_PATH>\\.ralph\\current-loop-id" 2026-02-03T06:21:01.942556Z DEBUG ralph::loop_runner: Created events file for this run: .ralph/events-20260203-062101.jsonl 2026-02-03T06:21:01.942636Z DEBUG ralph_core::event_loop: Multi-hat mode: 4 custom hats + Ralph as fallback 2026-02-03T06:21:01.942793Z DEBUG ralph_core::event_loop: Published spec.start event topic="spec.start" 2026-02-03T06:21:01.942997Z DEBUG ralph_core::event_logger: Event logged topic=spec.start iteration=0 2026-02-03T06:21:02.056757Z DEBUG ralph::loop_runner: Execution mode configured execution_mode=autonomous 2026-02-03T06:21:02.057313Z WARN ralph::loop_runner: Failed to record loop start in history: I/O error: File locking not supported on this platform 2026-02-03T06:21:02.057354Z DEBUG ralph::loop_runner: Iteration 1/100 - ralph active 2026-02-03T06:21:02.057453Z DEBUG ralph_core::event_loop: build_prompt: routing to HatlessRalph (multi-hat coordinator mode), active_hats: ["spec_writer"] 2026-02-03T06:21:02.057472Z INFO ralph_core::event_loop: Memory injection check: enabled=true, inject=Auto, workspace_root="<REPO_PATH>" 2026-02-03T06:21:02.057481Z INFO ralph_core::event_loop: Looking for memories at: "<REPO_PATH>\\.ralph/agent/memories.md" (exists: false) 2026-02-03T06:21:02.058599Z INFO ralph_core::event_loop: Successfully loaded 0 memories from store 2026-02-03T06:21:02.058609Z INFO ralph_core::event_loop: Memory store is empty - no memories to inject 2026-02-03T06:21:02.058622Z DEBUG ralph_core::event_loop: Injected ralph-tools skill from registry 2026-02-03T06:21:02.058796Z DEBUG ralph_core::event_loop: Scratchpad not found at "<REPO_PATH>\\.ralph\\agent\\scratchpad.md", skipping injection 2026-02-03T06:21:02.061378Z DEBUG ralph::loop_runner: Using global backend for 'spec_writer': claude 2026-02-03T06:21:02.066745Z DEBUG ralph_adapters::cli_backend: Built CLI command command=claude args_count=7 prompt_len=16960 interactive=false uses_stdin=false uses_temp_file=true 2026-02-03T06:21:02.267857Z DEBUG ralph_adapters::pty_executor: Spawning PTY output reader thread (streaming mode) 2026-02-03T06:21:55.043368Z INFO ralph_tui::app: Ctrl+C detected, signaling main loop 2026-02-03T06:21:55.043832Z INFO ralph_core::event_loop: Wrapping up: interrupted. 0 iterations in 53s. reason=interrupted iterations=0 duration=53s 2026-02-03T06:21:55.043866Z DEBUG ralph_core::event_logger: Event logged topic=loop.terminate iteration=0 2026-02-03T06:21:55.070403Z WARN ralph::loop_runner: Failed to record termination in history: I/O error: File locking not supported on this platform 2026-02-03T06:21:55.070417Z WARN ralph::loop_runner: Failed to deregister loop from registry: File locking not supported on this platform ``` ### Config / preset file spec-driven
kerem 2026-02-27 10:21:59 +03:00
Author
Owner

@The-Zona-Zoo commented on GitHub (Feb 3, 2026):

Analysis

Disclaimer: Claude Code analyzing with the help of my full workspace .ralph output


Root Cause Hypothesis: PTY + --output-format stream-json on Windows ConPTY

After investigating the codebase, I found a key difference between ralph plan (which works) and ralph run (which hangs):

ralph plan - Works

From sop_runner.rs:180-191:

  • Uses std::process::Command with inherited stdio (NOT PTY)
  • Uses CliBackend::for_interactive_prompt("claude")claude_interactive()
  • Command: claude --dangerously-skip-permissions --disallowedTools=... "prompt"

ralph run - Hangs

From loop_runner.rs:

  • Uses PTY via portable-pty (ConPTY on Windows)
  • Uses CliBackend::claude() with these flags:
    --dangerously-skip-permissions
    --verbose
    --output-format stream-json ← KEY DIFFERENCE
    --disallowedTools=...
    -p "prompt"

The Bug

The combination of Windows ConPTY + --output-format stream-json appears to cause Claude CLI to hang. Possible reasons:

  1. ConPTY buffering: Windows ConPTY may buffer NDJSON output differently than Unix PTY, preventing output from reaching the reader thread
  2. Claude's stream-json mode + ConPTY: Claude's NDJSON streaming mode may expect terminal capabilities that ConPTY doesn't properly emulate
  3. No output = infinite block: The PTY reader thread in pty_executor.rs:430 calls reader.read() which blocks forever waiting for data that never arrives

Evidence from Logs

DEBUG ralph_adapters::pty_executor: Spawning PTY output reader thread (streaming mode)
← hangs here indefinitely until Ctrl+C

The reader spawns but reader.read() blocks because Claude isn't producing output through ConPTY.

Potential Fixes

  1. Windows fallback: On Windows, skip PTY and use std::process::Command with piped I/O (like ralph plan does)
  2. Skip --output-format stream-json on Windows: Use text output format instead when running on Windows
  3. Add startup timeout: If no output is received within N seconds after spawn, fall back to non-PTY execution or error with a helpful message

Analysis performed by reviewing: pty_executor.rs, cli_backend.rs, loop_runner.rs, sop_runner.rs

<!-- gh-comment-id:3839386754 --> @The-Zona-Zoo commented on GitHub (Feb 3, 2026): ## Analysis *Disclaimer: Claude Code analyzing with the help of my full workspace .ralph output* --- ## Root Cause Hypothesis: PTY + `--output-format stream-json` on Windows ConPTY After investigating the codebase, I found a key difference between `ralph plan` (which works) and `ralph run` (which hangs): ### `ralph plan` - Works ✅ From `sop_runner.rs:180-191`: - Uses **`std::process::Command`** with inherited stdio (NOT PTY) - Uses `CliBackend::for_interactive_prompt("claude")` → `claude_interactive()` - Command: `claude --dangerously-skip-permissions --disallowedTools=... "prompt"` ### `ralph run` - Hangs ❌ From `loop_runner.rs`: - Uses **PTY via `portable-pty`** (ConPTY on Windows) - Uses `CliBackend::claude()` with these flags: --dangerously-skip-permissions --verbose --output-format stream-json ← KEY DIFFERENCE --disallowedTools=... -p "prompt" ## The Bug The combination of **Windows ConPTY + `--output-format stream-json`** appears to cause Claude CLI to hang. Possible reasons: 1. **ConPTY buffering**: Windows ConPTY may buffer NDJSON output differently than Unix PTY, preventing output from reaching the reader thread 2. **Claude's stream-json mode + ConPTY**: Claude's NDJSON streaming mode may expect terminal capabilities that ConPTY doesn't properly emulate 3. **No output = infinite block**: The PTY reader thread in `pty_executor.rs:430` calls `reader.read()` which blocks forever waiting for data that never arrives ## Evidence from Logs DEBUG ralph_adapters::pty_executor: Spawning PTY output reader thread (streaming mode) ← hangs here indefinitely until Ctrl+C The reader spawns but `reader.read()` blocks because Claude isn't producing output through ConPTY. ## Potential Fixes 1. **Windows fallback**: On Windows, skip PTY and use `std::process::Command` with piped I/O (like `ralph plan` does) 2. **Skip `--output-format stream-json` on Windows**: Use text output format instead when running on Windows 3. **Add startup timeout**: If no output is received within N seconds after spawn, fall back to non-PTY execution or error with a helpful message --- *Analysis performed by reviewing: `pty_executor.rs`, `cli_backend.rs`, `loop_runner.rs`, `sop_runner.rs`*
Author
Owner

@mikeyobrien commented on GitHub (Feb 3, 2026):

This is not a bug, windows is not supported. Welcome to add support via PR but it's not a priority for me at the moment.

Is there anything preventing using WSL?

<!-- gh-comment-id:3842631014 --> @mikeyobrien commented on GitHub (Feb 3, 2026): This is not a bug, windows is not supported. Welcome to add support via PR but it's not a priority for me at the moment. Is there anything preventing using WSL?
Author
Owner

@The-Zona-Zoo commented on GitHub (Feb 3, 2026):

Makes sense, I originally thought that was the case, but when reading the installation prerequisites it says windows is supported without a mention of WSL. Maybe that should be changed until it is properly supported.

<!-- gh-comment-id:3842748983 --> @The-Zona-Zoo commented on GitHub (Feb 3, 2026): Makes sense, I originally thought that was the case, but when reading the [installation prerequisites](https://mikeyobrien.github.io/ralph-orchestrator/installation/?h=windows#prerequisites) it says windows is supported without a mention of WSL. Maybe that should be changed until it is properly supported.
Author
Owner

@mikeyobrien commented on GitHub (Feb 3, 2026):

Oof, sorry about that. I'll get that fixed.

<!-- gh-comment-id:3843481249 --> @mikeyobrien commented on GitHub (Feb 3, 2026): Oof, sorry about that. I'll get that fixed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ralph-orchestrator#59
No description provided.