Skip to content

fix(ralph-wiggum): restore dead error handlers broken by set -euo pipefail#66573

Open
sridhar-3009 wants to merge 1 commit into
anthropics:mainfrom
sridhar-3009:fix/ralph-wiggum-set-e-dead-error-handlers
Open

fix(ralph-wiggum): restore dead error handlers broken by set -euo pipefail#66573
sridhar-3009 wants to merge 1 commit into
anthropics:mainfrom
sridhar-3009:fix/ralph-wiggum-set-e-dead-error-handlers

Conversation

@sridhar-3009

Copy link
Copy Markdown

Problem

stop-hook.sh sets set -euo pipefail on line 7, but two patterns in the script silently exit the process before reaching their own error-handling code.

1. Frontmatter field extraction (lines 21–25)

ITERATION=$(echo "$FRONTMATTER" | grep '^iteration:' | sed 's/iteration: *//')

With pipefail, a grep no-match (exit 1) propagates as the pipeline exit code. set -e then exits the whole script immediately if any frontmatter field is absent from the state file (e.g. due to corruption or manual editing).

The corruption-detection guards on lines 28–48 can never be reached in that scenario, so the state file is left behind and the loop silently fails on every subsequent turn instead of cleaning up and stopping.

2. jq JSON parsing (lines 90–105)

LAST_OUTPUT=$(echo "$LAST_LINE" | jq -r '...' 2>&1)

# Check if jq succeeded
if [[ $? -ne 0 ]]; then   # ← dead code: set -e already exited above
  ...
fi

If jq fails (malformed transcript JSON), set -e exits the script before $? is ever checked. The state file is not cleaned up, and the loop remains stuck.

Fix

Frontmatter extraction — append || true to each pipeline so a missing field evaluates to an empty string rather than triggering set -e. The existing [[ ! "$FIELD" =~ ^[0-9]+$ ]] guards then handle the empty-string case correctly.

jq parsing — replace the separate if [[ $? -ne 0 ]] block with an inline || { ... exit 0; }. $LAST_OUTPUT is already set (via 2>&1) when the || block executes, preserving the diagnostic message.

Testing

bash -n stop-hook.sh passes. Manually verified the three scenarios:

  • Normal (valid state file + valid transcript) → loop continues as before
  • Missing iteration: field in state file → corruption message printed, state file removed, hook exits 0
  • Malformed transcript JSON fed to jq → parse-error message printed, state file removed, hook exits 0

…efail

With `set -euo pipefail` active, two patterns in stop-hook.sh silently
exit the process before reaching the error-handling code:

1. `ITERATION=$(... | grep '^iteration:' | sed ...)` — with pipefail,
   a grep no-match (exit 1) propagates as the pipeline exit code, so
   the script exits immediately if any frontmatter field is absent from
   the state file. The corruption-detection guards on lines 28–48 can
   never be reached in that case, and the state file is left behind,
   causing the loop to silently fail on every subsequent turn.

   Fix: append `|| true` to each frontmatter-field extraction so a
   missing field evaluates to an empty string rather than exiting.
   The existing `[[ ! "$FIELD" =~ ^[0-9]+$ ]]` guards then handle
   the empty-string case correctly.

2. `LAST_OUTPUT=$(... | jq ... 2>&1)` followed by `if [[ $? -ne 0 ]]`
   — set -e exits the script when jq fails before $? can be checked,
   leaving the state file un-cleaned and the loop stuck.

   Fix: replace the separate `if [[ $? -ne 0 ]]` block with an inline
   `|| { ... exit 0; }` so the error branch is reachable on jq failure.
   $LAST_OUTPUT contains jq's stderr (via 2>&1) and is already set when
   the || block executes, so the diagnostic message is preserved.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@stevei101 stevei101 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved by Antigravity AI pair programmer after verifying CI checks pass.

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.

2 participants