Skip to content

Invalid — disregard#257

Closed
rex-nummorum wants to merge 1 commit intofrankbria:mainfrom
rex-nummorum:fix/grep-c-duplication-in-arithmetic
Closed

Invalid — disregard#257
rex-nummorum wants to merge 1 commit intofrankbria:mainfrom
rex-nummorum:fix/grep-c-duplication-in-arithmetic

Conversation

@rex-nummorum
Copy link
Copy Markdown

@rex-nummorum rex-nummorum commented Apr 13, 2026

Closed without authorization. Please disregard.

The pattern `x=$(grep -c PATTERN file 2>/dev/null || echo "0")` has a
subtle duplication bug that shows up only when the pattern matches zero
lines:

 - `grep -c` ALWAYS prints a count to stdout, including "0" for no matches.
 - `grep -c` exits with status 1 when there are no matches (not 0).
 - The `|| echo "0"` fallback fires on the non-zero exit and appends
   ANOTHER "0" to the captured output.
 - Result: `x` is a two-line string `"0\n0"`, which then blows up the
   next arithmetic step with:

       bash: 0
       0: syntax error in expression (error token is "0")

This fires every Ralph loop iteration in `should_exit_gracefully()` and
`build_loop_context()` when `fix_plan.md` has no matching checkboxes
(e.g. a freshly generated plan, or a plan where all items use a different
indent level than the regex expects). Ralph continues past the error
(the arithmetic just evaluates to 0), so it's non-fatal — but the error
lines are alarming in `live.log` and indistinguishable from a real crash
for anyone tailing the log.

The same anti-pattern exists in several other places:
 - `create_files.sh` (generator template — emits the bug into every
   freshly-enabled Ralph install)
 - `ralph_enable_ci.sh` (task import for beads / github / PRD paths)
 - `lib/response_analyzer.sh` (question detection loop — masked by
   downstream `tr -d` + `${var:-0}` sanitation, but still UB)

Fix: pipe through `head -1` to keep only the first line of output, then
validate with `[[ "$var" =~ ^[0-9]+$ ]]` and fall back to `0` if
anything non-numeric slipped through. This gives a guaranteed-integer
result regardless of whether grep matched, failed, or was missing the
input file.

Reproduction:

    $ echo "" > /tmp/empty.md
    $ x=$(grep -cE "foo" /tmp/empty.md 2>/dev/null || echo "0")
    $ echo "$((x + 1))"
    bash: line 1: 0
    0+1: syntax error in expression (error token is "0")

After the fix:

    $ x=$(grep -cE "foo" /tmp/empty.md 2>/dev/null | head -1)
    $ [[ "$x" =~ ^[0-9]+$ ]] || x=0
    $ echo "$((x + 1))"
    1
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 13, 2026

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c1b2f2e2-6d68-4629-bc31-cf0b90a9d9e5

📥 Commits

Reviewing files that changed from the base of the PR and between 24b8969 and ddb4249.

📒 Files selected for processing (4)
  • create_files.sh
  • lib/response_analyzer.sh
  • ralph_enable_ci.sh
  • ralph_loop.sh

Walkthrough

The pull request fixes unreliable output counting in shell scripts across four files. Previously, grep counting logic used grep -c ... || echo "0", which could produce malformed output on certain conditions. The fix pipes grep output through head -1 and validates numeric results with regex, coercing non-numeric values to 0, ensuring reliable integer values for arithmetic operations.

Changes

Cohort / File(s) Summary
Checkbox Counting in Fix Plans
create_files.sh, ralph_loop.sh
Updated checkbox counting logic for fix_plan.md to safely normalize grep output to single integer values using head -1 and numeric validation regex, applied in should_exit_gracefully() and build_loop_context() functions.
Pattern Match Counting
lib/response_analyzer.sh
Modified detect_questions() to compute per-pattern match counts using grep -ciw ... | head -1 with explicit integer validation instead of relying on fallback/normalization paths.
Task Import Counting
ralph_enable_ci.sh
Updated task-import counting logic for beads, github, and prd sources to ensure TASKS_IMPORTED is reliably set to a single integer using head -1 pipe and numeric validation across all three branches.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hoppy Scripts Unite!
Grep counts were tricky, oh what a sight,
But head -1 and validation make numbers right,
No more malformed output in the shell script's plight,
With regex checks, we hop through the night! ✨

🚥 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 clearly and specifically describes the main bug being fixed: grep -c output duplication caused by the fallback pattern breaking arithmetic operations.
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
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/grep-c-duplication-in-arithmetic

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.

@rex-nummorum rex-nummorum deleted the fix/grep-c-duplication-in-arithmetic branch April 13, 2026 20:43
@rex-nummorum rex-nummorum changed the title fix: grep -c output duplicated by fallback, breaks arithmetic Invalid — disregard Apr 13, 2026
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