Skip to content

fix(live-mode): crash with text output format (#164)#166

Merged
frankbria merged 2 commits into
mainfrom
fix/live-mode-text-format-164
Feb 7, 2026
Merged

fix(live-mode): crash with text output format (#164)#166
frankbria merged 2 commits into
mainfrom
fix/live-mode-text-format-164

Conversation

@frankbria
Copy link
Copy Markdown
Owner

@frankbria frankbria commented Feb 7, 2026

Summary

Fixes #164 — Live/monitor mode (ralph --live) crashed with stdbuf: unrecognized option '--verbose' when CLAUDE_OUTPUT_FORMAT="text" was set in .ralphrc.

Root cause: build_claude_command() was only called inside a CLAUDE_OUTPUT_FORMAT == "json" gate, leaving CLAUDE_CMD_ARGS empty for text mode. The live mode code then appended --verbose --include-partial-messages to an empty array, causing stdbuf to interpret them as its own flags.

Three coordinated fixes:

  • Override text→json when live mode is active (stream-json is inherently JSON-based)
  • Always call build_claude_command() regardless of output format (text mode users now also get allowed-tools, session continuity, etc.)
  • Add safety check for empty CLAUDE_CMD_ARGS before live mode command construction

Also updates help text for --live and --output-format to document the auto-switch behavior.

Test plan

  • 6 new tests added to tests/unit/test_cli_modern.bats (TDD — written before implementation)
  • Full test suite passes: 490 tests, 0 failures
  • Manual verification: ralph --live with CLAUDE_OUTPUT_FORMAT="text" in .ralphrc no longer crashes
  • Manual verification: ralph --live with default JSON format still works as before

Summary by CodeRabbit

  • Bug Fixes
    • Live mode now forces JSON output for streaming and robustly falls back to legacy mode when modern CLI invocation fails; disables live streaming if required command/args are missing.
  • Tests
    • Added unit tests covering live-mode JSON override, safety checks, modern CLI invocation, and related edge cases.
  • Documentation
    • Updated CLI docs to note live mode requires JSON and will auto-switch from text.

Live/monitor mode crashed with `stdbuf: unrecognized option '--verbose'`
when CLAUDE_OUTPUT_FORMAT="text" because build_claude_command() was only
called inside a JSON-only gate, leaving CLAUDE_CMD_ARGS empty.

Three coordinated fixes:
- Override text→json when live mode is active (stream-json requires JSON)
- Always call build_claude_command() regardless of output format
- Add safety check for empty CLAUDE_CMD_ARGS before live mode construction

Also updates help text for --live and --output-format to document the
auto-switch behavior.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 7, 2026

Walkthrough

Live mode in ralph_loop.sh now forces JSON output for streaming, always attempts to build the modern Claude CLI command, adds safety checks and fallbacks for live streaming, transforms JSON to stream-json with streaming flags, and updates tests and docs to cover these behaviors.

Changes

Cohort / File(s) Summary
Live Mode & CLI
ralph_loop.sh
Force JSON when --live is used (overriding CLAUDE_OUTPUT_FORMAT with a warning), always call build_claude_command, add safety checks for built command and CLAUDE_CMD_ARGS, fall back to legacy on failures, transform jsonstream-json and append streaming flags (--verbose, --include-partial-messages), update CLI help text.
Tests
tests/unit/test_cli_modern.bats
Add comprehensive LIVE MODE + TEXT FORMAT tests covering command building for text/json, live-mode override behavior, safety checks for empty CLAUDE_CMD_ARGS, prompt handling (multiline/missing), array-argument handling, and inclusion of modern CLI flags. (Duplicate copy of the new test block present in diff.)
Docs
CLAUDE.md
Update test counts and CLI Options note to state live mode requires JSON and will auto-switch from text to JSON; expand test description to reference live-mode text format fix (#164).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 I hopped into live mode, nose twitching with cheer,
Switched text to JSON so streaming's crystal clear.
stream-json dances, flags flutter in line,
Safety checks guard the burrow — all systems fine. 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing a live-mode crash when text output format is set, which is the core problem addressed in the PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/live-mode-text-format-164

No actionable comments were generated in the recent review. 🎉


Comment @coderabbitai help to get the list of available commands and usage tips.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Feb 7, 2026

Force JSON output in live mode to fix crash with text format and unconditionally build modern CLI command in ralph_loop.sh

Add a guard in execute_claude_code to auto-switch --live from text to JSON and abort live mode if the modern command or CLAUDE_CMD_ARGS is missing; invoke build_claude_command for all formats; update CLI help and tests; adjust docs and test counts.

📍Where to Start

Start in execute_claude_code within ralph_loop.sh, then review the new tests in tests/unit/test_cli_modern.bats.


Macroscope summarized 131b95d.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

Code Review Summary

This PR successfully fixes issue No.164 by addressing the crash when --live mode is used with CLAUDE_OUTPUT_FORMAT="text". The implementation is well-structured with three coordinated fixes and comprehensive test coverage.

✅ Strengths

1. Root Cause Analysis
The PR correctly identifies that build_claude_command() was only called within a JSON-only gate, leaving CLAUDE_CMD_ARGS empty for text mode. This caused stdbuf to interpret streaming flags as its own arguments.

2. Implementation Quality

  • Logical override: Lines 1052-1055 appropriately override text→json when live mode is active, with clear warning message
  • Removed artificial gate: Lines 1060-1065 now call build_claude_command() unconditionally, which is correct since the function already handles both formats
  • Safety check: Lines 1094-1098 add defensive programming to prevent regression if CLAUDE_CMD_ARGS is somehow empty
  • Clear user communication: Help text updates (lines 1623, 1632) document the auto-switch behavior

3. Test Coverage
Six new tests in test_cli_modern.bats provide excellent coverage:

  • Tests 1-2: Verify build_claude_command() works for both text and json formats
  • Tests 3-4: Validate the live mode override logic and conditional behavior
  • Test 5: Verify safety check exists
  • Test 6: Confirm the JSON-only gate has been removed

The tests are well-structured and use TDD approach (written before implementation).

4. Alignment with CLAUDE.md Standards

  • Conventional commit format: fix(live-mode): crash with text output format (#164)
  • Clear, detailed commit message explaining the three fixes
  • References the issue number appropriately
  • Test suite passes (490 tests as stated in PR description)

🔍 Observations

1. Redundant Safety Check
The safety check at lines 1094-1098 is defensive but may be redundant since build_claude_command() is now always called before this point. However, this redundancy is acceptable as defense-in-depth and makes the code more resilient to future refactoring.

2. Format Override Placement
The format override (lines 1052-1055) happens before build_claude_command() is called, which is correct. This ensures the function receives the correct format and builds the appropriate command array.

3. Log Message Clarity
Line 1062 now shows the actual format being used, providing clear feedback.

🎯 Suggestions (Minor/Optional)

1. Update CLAUDE.md Documentation
While the help text is updated, consider adding a note in CLAUDE.md under the "Live Mode" or "Modern CLI Configuration" sections documenting this auto-switch behavior for future maintainers.

2. Test Enhancement Opportunity
Consider adding an integration test that actually runs ralph --live with text format in a test project to verify end-to-end behavior (though this may be outside the scope of this PR).

✅ Security & Performance

  • No security concerns: The changes are defensive and don't introduce new attack surfaces
  • No performance impact: Format override and safety check are O(1) operations
  • No breaking changes: The override is transparent to users and maintains backward compatibility

📋 Final Verdict

Approve with enthusiasm. This PR:

  • Correctly identifies and fixes the root cause
  • Implements a clean solution with three coordinated fixes
  • Adds comprehensive test coverage (6 new tests)
  • Follows project conventions and quality standards
  • Improves user experience with clear messaging

The implementation is production-ready. The minor suggestions above are optional enhancements that could be addressed in follow-up PRs if desired.

Test Status: PR states 490 tests pass with 0 failures. Recommend verifying CI pipeline completion before merge.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

Review Summary

Status: ✅ Approved

This PR provides an excellent fix for issue #164 with a well-thought-out three-layer approach. All 490 tests pass.


Code Quality and Best Practices

  • Clean implementation: The fix addresses the root cause without unnecessary complexity
  • Clear documentation: Updated help text for and flags accurately documents the auto-switch behavior
  • Defensive programming: Added safety check (lines 1094-1099) prevents crashes even if is unexpectedly empty
  • User-friendly messaging: Warning message clearly explains the format override behavior

Implementation Highlights

The three-layer fix is robust:

  1. Format override (lines 1052-1055): Live mode auto-switches text → json (stream-json is inherently JSON-based)
  2. Unconditional call (lines 1058-1063): now runs regardless of output format
  3. Safety check (lines 1094-1099): Falls back to background mode if is empty

This layered approach ensures the fix works even if one layer fails.

Test Coverage

  • 6 new tests added (test_cli_modern.bats:677-765)
  • Tests 34-39 verify:
    • Text mode populates (fixes core issue)
    • JSON mode includes (regression check)
    • Live mode override logic exists
    • Override preserves JSON mode unchanged
    • Safety check prevents live mode with empty args
    • is called unconditionally
  • All 490 tests pass

Behavior Clarification

The auto-switch behavior is correct and intentional:

  • Live mode requires JSON output (stream-json functionality)
  • Users with in get auto-upgraded to JSON when using or
  • This is documented in help text: Note: --live mode requires JSON and will auto-switch

Alternative approaches (disabling live mode for text) would be more confusing than this technical necessity.

Minor Suggestions (Optional)

Consider adding a README or documentation section explaining when and why output format gets auto-switched, to help users understand this behavior without having to dig into the code.


Recommendation: Merge this PR. The fix is well-tested, properly documented, and addresses the issue thoroughly without introducing regressions.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

Review comment posted successfully. The PR addresses issue #164 with a clean, well-tested fix that adds a safety-first three-layer approach:

  1. Auto-override text → json when live mode is active
  2. Always call build_claude_command() regardless of output format
  3. Safety check to prevent crashes if CLAUDE_CMD_ARGS is empty

All 490 tests pass, including 6 new tests specifically for this fix. The implementation maintains code quality, security (shell-injection protection preserved), and provides clear user feedback. ✅

New%20session%20-%202026-02-07T18%3A04%3A12.286Z
opencode session  |  github run

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ralph_loop.sh (1)

1060-1099: ⚠️ Potential issue | 🟠 Major

Disable live mode when build_claude_command fails.

If build_claude_command fails, CLAUDE_CMD_ARGS still contains the base command, so live mode can run without prompt/flags and hang or run interactively. Gate live mode on a successful build (use_modern_cli=true), not just a non-empty array.

🔧 Suggested fix
-    if build_claude_command "$PROMPT_FILE" "$loop_context" "$session_id"; then
+    if build_claude_command "$PROMPT_FILE" "$loop_context" "$session_id"; then
         use_modern_cli=true
         log_status "INFO" "Using modern CLI mode (${CLAUDE_OUTPUT_FORMAT} output)"
     else
         log_status "WARN" "Failed to build modern CLI command, falling back to legacy mode"
+        if [[ "$LIVE_OUTPUT" == "true" ]]; then
+            log_status "ERROR" "Live mode requires a built Claude command. Falling back to background mode."
+            LIVE_OUTPUT=false
+        fi
     fi
@@
-    if [[ "$LIVE_OUTPUT" == "true" ]]; then
-        # Safety check: CLAUDE_CMD_ARGS must be populated for live mode
-        if [[ ${`#CLAUDE_CMD_ARGS`[@]} -eq 0 ]]; then
-            log_status "ERROR" "CLAUDE_CMD_ARGS is empty — cannot build live mode command. Falling back to background mode."
-            LIVE_OUTPUT=false
-        fi
-    fi
+    if [[ "$LIVE_OUTPUT" == "true" ]]; then
+        # Safety check: live mode requires a successfully built modern command
+        if [[ "$use_modern_cli" != "true" || ${`#CLAUDE_CMD_ARGS`[@]} -eq 0 ]]; then
+            log_status "ERROR" "Live mode requires a built Claude command. Falling back to background mode."
+            LIVE_OUTPUT=false
+        fi
+    fi
🤖 Fix all issues with AI agents
In `@tests/unit/test_cli_modern.bats`:
- Around line 749-763: The sed range in the test is case-sensitive and currently
uses the wrong end header ("execute Claude Code") causing an empty range; update
the sed invocation in tests/unit/test_cli_modern.bats so the range matches the
actual header (e.g., "Execute Claude Code") or make the range case-insensitive
(use sed -n '/# Build the Claude CLI command/,/Execute Claude Code/p' or
equivalent), and ensure the subsequent grep still looks for the actual call to
build_claude_command (keep reference to build_claude_command) so the test
verifies the call site correctly.
- Around line 671-747: Add an integration test to exercise ralph_loop.sh
live-mode end-to-end: extend or create tests in test_loop_execution.bats that
(1) start ralph_loop.sh with LIVE_OUTPUT=true and CLAUDE_OUTPUT_FORMAT="text"
and assert the script overrides to json (inspect runtime env or captured command
using CLAUDE_OUTPUT_FORMAT/CLAUDE_CMD_ARGS), (2) simulate missing jq and stdbuf
by running the loop with a PATH that hides those binaries and assert the loop
falls back to non-jq/stdbuf behavior, and (3) ensure when CLAUDE_CMD_ARGS is
empty the loop detects length zero and falls back to background mode; reuse
symbols build_claude_command, CLAUDE_CMD_ARGS, LIVE_OUTPUT, and
CLAUDE_OUTPUT_FORMAT to locate logic in ralph_loop.sh and add assertions that
the loop performed the override or fallback behavior.
🧹 Nitpick comments (1)
ralph_loop.sh (1)

1623-1633: Sync CLAUDE.md with the new live‑mode auto‑switch behavior.

Help text now documents auto-switching; please update CLAUDE.md to match (or confirm it already does).

Based on learnings: Keep CLAUDE.md synchronized with the codebase by updating it when new commands are added, exit conditions change, or new Ralph loop behaviors are introduced.

Comment thread tests/unit/test_cli_modern.bats
Comment thread tests/unit/test_cli_modern.bats
- Disable live mode when build_claude_command fails (not just empty array)
- Strengthen safety check to verify use_modern_cli=true
- Fix case-sensitive sed range in test (execute→Execute)
- Update CLAUDE.md: auto-switch docs, test counts (484→490)
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

Follow-up Review - Additional Observations

I've reviewed the existing comments and the implementation. My previous reviews (comments from 2026-02-07) approved this PR with enthusiasm, and I stand by that assessment. However, I want to address one concern raised by CodeRabbit that warrants clarification:

Regarding the "Outside diff range" Comment

CodeRabbit suggested disabling live mode when build_claude_command fails. This concern is already addressed in the current implementation:

Lines 1060-1069 in ralph_loop.sh:

The code already disables live mode when build_claude_command fails (lines 1065-1068). The additional safety check at lines 1097-1103 provides defense-in-depth by also checking if CLAUDE_CMD_ARGS is empty.

Test Suite Validation

The test at lines 750-765 validates that the JSON-only gate has been removed, correctly verifying that build_claude_command is no longer gated behind a JSON-only conditional.

Summary

The implementation is robust and complete:

  1. ✅ Auto-switches text → json for live mode (lines 1051-1055)
  2. ✅ Always calls build_claude_command regardless of format (line 1060)
  3. ✅ Disables live mode if build_claude_command fails (lines 1065-1068)
  4. ✅ Additional safety check for empty CLAUDE_CMD_ARGS (lines 1097-1103)
  5. ✅ Comprehensive test coverage (6 new tests)
  6. ✅ Updated documentation in help text and CLAUDE.md

Recommendation remains: Approve and merge. All concerns have been properly addressed in the implementation.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

✅ PR Review: Approved

This PR successfully fixes issue #164 with a well-implemented solution that includes defensive programming and comprehensive test coverage.

CodeRabbit Feedback — All Addressed ✓

Commit 131b95d addressed all CodeRabbit review comments:

  1. Live mode disable on build failure (ralph_loop.sh:1065-1068): Live mode now disabled when fails
  2. Strengthened safety check (ralph_loop.sh:1098): Now verifies both AND non-empty
  3. Fixed sed range (test_cli_modern.bats:761): Changed from to to match actual header
  4. Updated CLAUDE.md: Added auto-switch documentation and updated test counts (484→490)

Implementation Quality

The three-layer fix is robust and production-ready:

  1. Format override (lines 1052-1055): Auto-switches text→json for live mode with clear warning
  2. Unconditional build (line 1060): now runs for all formats
  3. Safety checks (lines 1065-1068, 1098): Defense-in-depth preventing crashes

Test Coverage

  • 6 new tests in test_cli_modern.bats (lines 677-765)
  • 490 total tests passing
  • Tests verify all three fixes and edge cases

Assessment

  • Code quality: Excellent — clean, well-structured, follows conventions
  • Security: No concerns — shell injection protection maintained
  • Performance: No impact — O(1) operations
  • Breaking changes: None — auto-switch is transparent

Recommendation: Merge. All feedback addressed, tests pass, implementation is robust.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

PR Review: Approved

This PR successfully fixes issue #164 with a well-implemented solution that includes defensive programming and comprehensive test coverage.

CodeRabbit Feedback - All Addressed

Commit 131b95d addressed all CodeRabbit review comments:

  1. Live mode disable on build failure (ralph_loop.sh:1065-1068)
  2. Strengthened safety check (ralph_loop.sh:1098): Now verifies both use_modern_cli AND CLAUDE_CMD_ARGS
  3. Fixed sed range (test_cli_modern.bats:761): Changed to match actual header
  4. Updated CLAUDE.md: Added auto-switch documentation and updated test counts

Implementation Quality

Three-layer fix is robust and production-ready:

  • Format override: Auto-switches text to json for live mode
  • Unconditional build: build_claude_command runs for all formats
  • Safety checks: Defense-in-depth preventing crashes

Test Coverage

  • 6 new tests in test_cli_modern.bats
  • 490 total tests passing
  • Tests verify all three fixes and edge cases

Assessment

  • Code quality: Excellent - clean, well-structured, follows conventions
  • Security: No concerns - shell injection protection maintained
  • Performance: No impact
  • Breaking changes: None - auto-switch is transparent

Recommendation: Merge. All feedback addressed, tests pass, implementation is robust.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 7, 2026

Posted review comment confirming PR approval. All CodeRabbit feedback addressed, tests pass (490/490), implementation is production-ready with robust three-layer fix.

New%20session%20-%202026-02-07T23%3A56%3A36.924Z
opencode session  |  github run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Live/monitor mode fails with text output format - build_claude_command not called

1 participant