Skip to content

fix(ralph-loop): resolve unbound variable and use opencode run#104

Merged
marcusquinn merged 1 commit intomainfrom
feature/update-repo-to-use-latest-opencode-anth
Jan 15, 2026
Merged

fix(ralph-loop): resolve unbound variable and use opencode run#104
marcusquinn merged 1 commit intomainfrom
feature/update-repo-to-use-latest-opencode-anth

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Jan 15, 2026

Summary

  • Fix output_file: unbound variable error in ralph-loop-helper.sh EXIT trap
  • Replace deprecated opencode --print with opencode run --format json
  • Add RALPH_MODEL environment variable support for model selection
  • Print last 20 lines of tool output on failure for debugging

Changes

The ralph loop was crashing with line 786: output_file: unbound variable because:

  1. output_file was declared as local inside run_v2_loop() function
  2. The trap ... EXIT fires at script exit, after the function scope ends
  3. With set -u, referencing the now-unset variable caused the crash

Fix: Move output_file to script scope (line 72) so it persists for the EXIT trap.

Also updated the opencode invocation from the deprecated --print flag to opencode run --format json, and added debugging output when the tool fails.

Testing

  • ShellCheck passes (only SC1091 info about sourced file)
  • Manual verification of trap behavior

Summary by CodeRabbit

  • Chores
    • Enhanced error diagnostics by displaying the last 20 lines of tool output when execution fails, improving troubleshooting visibility.

✏️ Tip: You can customize this high-level summary in your review settings.

- Move output_file to script scope to fix EXIT trap unbound variable error
- Replace deprecated 'opencode --print' with 'opencode run --format json'
- Add RALPH_MODEL env var support for model selection
- Print last 20 lines of tool output on failure for debugging
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

Walkthrough

The .agent/scripts/ralph-loop-helper.sh script is refactored to introduce a global output_file variable for unified tool output capture, adjusts trap cleanup behavior from EXIT to RETURN, restructures the opencode tool invocation with optional model argument support, and adds conditional display of tool error output on non-zero exit codes.

Changes

Cohort / File(s) Summary
Output Capture & Error Handling Refactoring
.agent/scripts/ralph-loop-helper.sh
Introduces global output_file variable for shared tool output capture; modifies trap from EXIT to RETURN cleanup; restructures opencode tool invocation to support optional --model argument via array construction; adds conditional printing of last 20 lines of output on non-zero exit; maintains JSON event parsing via updated capture method

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A global path emerges clean and bright,
Output flows through traps that catch just right,
When models dance with options in the array,
Errors whisper their tales without delay,
Zero debt preserved, automation's delight! ✨

🚥 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 describes the main changes: fixing an unbound variable issue and updating to use the opencode run command.
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

🧹 Recent nitpick comments
.agent/scripts/ralph-loop-helper.sh (1)

72-74: Comment-code mismatch: trap is RETURN, not EXIT.

The variable declaration correctly resolves the unbound variable issue under set -u. However, the comment mentions "EXIT trap" while line 265 actually uses a RETURN trap. Consider updating for accuracy:

-# Output file for tool capture (shared with EXIT trap)
+# Output file for tool capture (shared with RETURN trap)
 output_file=""

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f3b46a and bdbf84e.

📒 Files selected for processing (1)
  • .agent/scripts/ralph-loop-helper.sh
🧰 Additional context used
📓 Path-based instructions (1)
.agent/scripts/*.sh

⚙️ CodeRabbit configuration file

.agent/scripts/*.sh: Automation scripts - focus on:

  • Reliability and robustness
  • Clear logging and feedback
  • Proper exit codes
  • Error recovery mechanisms

Files:

  • .agent/scripts/ralph-loop-helper.sh
🧬 Code graph analysis (1)
.agent/scripts/ralph-loop-helper.sh (2)
.agent/scripts/full-loop-helper.sh (1)
  • print_warning (91-95)
.agent/scripts/quality-loop-helper.sh (1)
  • print_warning (105-109)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Audit Log
  • GitHub Check: Security Block Notification
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
.agent/scripts/ralph-loop-helper.sh (4)

264-265: RETURN trap cleans up on function exit—consider edge cases.

The fix correctly ensures output_file is defined before the trap references it. Using RETURN instead of EXIT scopes cleanup to the function, which is appropriate here.

One consideration: if the script is terminated by an untrapped signal (e.g., SIGKILL), the temp file persists. For most use cases this is acceptable since /tmp is ephemeral, but if you want belt-and-suspenders cleanup, you could add a script-level EXIT trap as well.

The ${output_file:-} pattern is a solid defensive measure.


316-319: Helpful debugging output on tool failure.

Printing the last 20 lines on non-zero exit provides valuable debugging context. The -s check appropriately guards against empty files.

For slightly better readability, consider adding visual separators:

💡 Optional enhancement for output clarity
         if [[ -s "$output_file" ]]; then
             print_warning "Tool output (last 20 lines):"
+            echo "---"
             tail -n 20 "$output_file"
+            echo "---"
         fi

323-325: Good inline documentation explaining the grep behavior.

The comment clarifies why grep for the <promise> tag works despite JSON output—helpful context for future maintainers. The raw text search approach is pragmatic and avoids JSON parsing complexity.


296-300: Array-based argument construction with optional model support is correctly implemented.

The code properly:

  • Uses array expansion to safely pass arguments (preventing word-splitting vulnerabilities)
  • Checks RALPH_MODEL with ${RALPH_MODEL:-} to handle unset variables under set -u
  • Captures both stdout and stderr for debugging
  • Preserves exit codes for proper error handling

The opencode run command correctly accepts the prompt as a positional argument before format flags, as confirmed by codebase patterns throughout the framework.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist
Copy link

Summary of Changes

Hello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical runtime error in the ralph-loop-helper.sh script by ensuring a temporary file variable remains accessible to the script's exit trap. It also modernizes the opencode command invocation, introduces an environment variable for flexible model selection, and significantly improves debugging capabilities by logging tool output upon failure.

Highlights

  • Unbound Variable Fix: Resolved an unbound variable error in the ralph-loop-helper.sh script's EXIT trap by moving the output_file variable to a global scope, ensuring it persists throughout the script's execution.
  • Opencode Command Update: Replaced the deprecated opencode --print command with opencode run --format json for modern usage, aligning with current opencode API practices.
  • Model Selection Support: Added support for the RALPH_MODEL environment variable, allowing users to dynamically select the model used by opencode.
  • Enhanced Debugging: Implemented a feature to print the last 20 lines of tool output to stderr when a tool fails, significantly aiding in debugging and troubleshooting.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@sonarqubecloud
Copy link

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 261 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Thu Jan 15 01:23:26 UTC 2026: Code review monitoring started
Thu Jan 15 01:23:27 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 261
Thu Jan 15 01:23:27 UTC 2026: Qlty - 0 issues found, auto-formatting applied
Thu Jan 15 01:23:29 UTC 2026: Codacy analysis completed with auto-fixes

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 261
  • VULNERABILITIES: 0

Generated on: Thu Jan 15 01:24:04 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively resolves a critical unbound variable crash in the ralph-loop by correctly scoping the output_file variable. The changes also modernize the opencode invocation and improve debugging by showing tool output on failure, which are great enhancements. The implementation is clean, especially the safe handling of command arguments. I have one suggestion to further improve the robustness of the temporary file cleanup logic.

output_file=$(mktemp)
trap 'rm -f "$output_file"' EXIT
output_file="$(mktemp)"
trap 'rm -f "${output_file:-}"' RETURN

Choose a reason for hiding this comment

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

high

Using a RETURN trap for cleanup can lead to leaked temporary files if the script exits unexpectedly (e.g., due to a signal like SIGINT/Ctrl-C, or a set -e exit) before the function returns. An EXIT trap is more robust as it fires regardless of how the script terminates.

Since output_file is now a global variable, using an EXIT trap is now safe from the original unbound variable issue and will ensure the temp file is always cleaned up, which is safer for resource management.

Suggested change
trap 'rm -f "${output_file:-}"' RETURN
trap 'rm -f "${output_file:-}"' EXIT

@augmentcode
Copy link

augmentcode bot commented Jan 15, 2026

🤖 Augment PR Summary

Summary: Fixes the ralph loop’s temp-file cleanup bug (unbound output_file) and updates OpenCode invocation for headless runs.
Changes: Uses opencode run --format json with optional RALPH_MODEL, and prints the last 20 lines of tool output on failures for easier debugging.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

readonly NC='\033[0m'

# Output file for tool capture (shared with EXIT trap)
output_file=""
Copy link

Choose a reason for hiding this comment

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

The comment says this is “shared with EXIT trap”, but in this diff the cleanup trap was changed to RETURN. If there’s no longer an EXIT trap using output_file, this comment is now misleading and could confuse future maintenance.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

output_file=$(mktemp)
trap 'rm -f "$output_file"' EXIT
output_file="$(mktemp)"
trap 'rm -f "${output_file:-}"' RETURN
Copy link

Choose a reason for hiding this comment

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

Worth double-checking that using a RETURN trap here matches the intended cleanup semantics: it won’t run on abrupt script exit (and can also persist beyond run_v2_loop() unless explicitly cleared), so the temp file may not always be removed when expected.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

@marcusquinn marcusquinn merged commit ebc6990 into main Jan 15, 2026
15 of 17 checks passed
@marcusquinn marcusquinn deleted the feature/update-repo-to-use-latest-opencode-anth branch February 21, 2026 01:59
marcusquinn added a commit that referenced this pull request Mar 8, 2026
…se args (GH#3816)

Address remaining unactioned CodeRabbit review feedback from PR #14:

- ralph-loop-helper.sh run_v2_loop: validate --max-iterations is a positive
  integer, --completion-promise is non-empty, --max-attempts is a positive
  integer. Previously these accepted any value silently.
- ralph-loop-helper.sh setup_loop: add matching validation for --max-iterations
  and --completion-promise for consistency.
- quality-loop-helper.sh: add --max-iterations validation to preflight_loop,
  pr_review_loop, and postflight_loop. All now reject non-positive-integer
  values with a clear error message instead of silently accepting them.

Other PR #14 findings (aider duplicate prompt, || true hiding failures, missing
tool existence check, invalid --monitor-duration, relative git_common_dir) were
already fixed in subsequent PRs #35, #104, #111, #396, #480.
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.

1 participant