Skip to content

fix(review): fail loudly on empty harness output#10

Merged
khaliqgant merged 1 commit into
mainfrom
fix/pr-reviewer-fail-loud-harness
May 28, 2026
Merged

fix(review): fail loudly on empty harness output#10
khaliqgant merged 1 commit into
mainfrom
fix/pr-reviewer-fail-loud-harness

Conversation

@khaliqgant

@khaliqgant khaliqgant commented May 28, 2026

Copy link
Copy Markdown
Member

Summary

  • make pr-reviewer surface non-zero harness exit codes and empty review output as explicit failures
  • post a visible GitHub/Slack failure artifact instead of silently continuing as if the PR was reviewed

Tests

  • npm run typecheck

Summary by cubic

Fail fast when the review harness exits non-zero or produces no review, and post visible failure notices to GitHub and Slack so bad runs don’t look successful.

  • Bug Fixes
    • Detect non-zero harness exitCode and empty review output and treat them as hard failures.
    • Add failReviewRun() to log the error, comment on the PR, notify Slack via SLACK_CHANNEL, and throw to stop the run.

Written for commit 2bbdd83. Summary will update on new commits.

Review in cubic

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR enhances error handling in the review process by adding exit code validation to reviewAndFix and introducing a centralized failReviewRun helper that logs errors, posts PR comments, sends Slack notifications, and halts execution when reviews fail.

Changes

Review Error Handling and Failure Reporting

Layer / File(s) Summary
Harness exit code checking and centralized failure notification
review/agent.ts
reviewAndFix now detects non-zero harness exit codes and empty output by stripping a trailing READY sentinel, triggering the new failReviewRun helper. failReviewRun centralizes failure behavior: logs errors, conditionally posts PR comments via ctx.github.comment, conditionally sends Slack warnings via ctx.slack.post with SLACK_CHANNEL, and throws an error to stop processing.

🎯 2 (Simple) | ⏱️ ~8 minutes

🐰 A harness fails, I see! With exit codes now revealed,
failReviewRun bounds to GitHub and Slack appealed,
Comments and warnings race across the screen,
Then throws an error clean—the best failure routine! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding failure handling for empty harness output, which matches the core purpose of the pull request.
Description check ✅ Passed The description is directly related to the changeset, explaining both the problem (non-zero exit codes and empty output being silently ignored) and the solution (explicit failures with GitHub/Slack notifications).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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/pr-reviewer-fail-loud-harness

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@review/agent.ts`:
- Around line 115-127: In failReviewRun, isolate GitHub and Slack notification
failures by wrapping the ctx.github.comment(...) call and the
ctx.slack.post(...) call in separate try/catch blocks so one exception doesn't
prevent the other from running; catch and log each error (use the existing
logger available in the function, e.g. ctx.logger.error or processLogger.error)
and continue, ensuring you still compute channel via input(ctx, 'SLACK_CHANNEL')
and use the same message and reason variables when sending notifications.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dbe0af55-d31d-4455-9fc3-0e82490de9dd

📥 Commits

Reviewing files that changed from the base of the PR and between 7176164 and 2bbdd83.

📒 Files selected for processing (1)
  • review/agent.ts

Comment thread review/agent.ts
Comment on lines +115 to +127
if (ctx.github?.comment) {
await ctx.github.comment(
{ owner: pr.owner, repo: pr.repo, number: pr.number },
message,
);
}
const channel = input(ctx, 'SLACK_CHANNEL');
if (channel && ctx.slack) {
await ctx.slack.post(
channel,
`:warning: pr-reviewer failed for PR #${pr.number} in *${pr.owner}/${pr.repo}*: ${reason}`,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant function and surrounding code with line numbers
nl -ba review/agent.ts | sed -n '80,170p'

# Locate failReviewRun definition and any callers/handling
rg -n "failReviewRun" review/agent.ts
rg -n "ctx\.github\.comment|ctx\.slack\.post" review/agent.ts

# Check if there's any higher-level try/catch in the file that could already isolate these failures
rg -n "try\s*[{]|catch\s*\(" review/agent.ts

Repository: AgentWorkforce/agents

Length of output: 108


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== review/agent.ts lines 80-170 (raw) ==="
sed -n '80,170p' review/agent.ts

echo
echo "=== failReviewRun occurrences ==="
rg -n "failReviewRun" review/agent.ts

echo
echo "=== ctx.github.comment / ctx.slack.post occurrences ==="
rg -n "ctx\.github\.comment|ctx\.slack\.post" review/agent.ts

echo
echo "=== try/catch occurrences in review/agent.ts ==="
rg -n "try\s*[{]|catch\s*\(" review/agent.ts

Repository: AgentWorkforce/agents

Length of output: 4405


Isolate GitHub/Slack notification failures in failReviewRun so one error doesn’t block the other.

failReviewRun calls await ctx.github.comment(...) and then await ctx.slack.post(...) without try/catch; if either throws, the other notification won’t be sent (there’s no surrounding error handling in this file).

Suggested fix
 async function failReviewRun(ctx: WorkforceCtx, pr: Pr, reason: string): Promise<never> {
   const message = [
     `pr-reviewer could not complete review for #${pr.number} in ${pr.owner}/${pr.repo}.`,
     reason,
     'No review was posted; this needs operator attention.',
   ].join('\n');
   ctx.log?.('error', 'pr-reviewer harness failed', {
     owner: pr.owner,
     repo: pr.repo,
     number: pr.number,
     reason,
   });
   if (ctx.github?.comment) {
-    await ctx.github.comment(
-      { owner: pr.owner, repo: pr.repo, number: pr.number },
-      message,
-    );
+    try {
+      await ctx.github.comment(
+        { owner: pr.owner, repo: pr.repo, number: pr.number },
+        message,
+      );
+    } catch (error) {
+      ctx.log?.('warn', 'pr-reviewer.fail-comment-post-failed', {
+        owner: pr.owner,
+        repo: pr.repo,
+        number: pr.number,
+        error: String(error),
+      });
+    }
   }
   const channel = input(ctx, 'SLACK_CHANNEL');
   if (channel && ctx.slack) {
-    await ctx.slack.post(
-      channel,
-      `:warning: pr-reviewer failed for PR #${pr.number} in *${pr.owner}/${pr.repo}*: ${reason}`,
-    );
+    try {
+      await ctx.slack.post(
+        channel,
+        `:warning: pr-reviewer failed for PR #${pr.number} in *${pr.owner}/${pr.repo}*: ${reason}`,
+      );
+    } catch (error) {
+      ctx.log?.('warn', 'pr-reviewer.fail-slack-post-failed', {
+        owner: pr.owner,
+        repo: pr.repo,
+        number: pr.number,
+        channel,
+        error: String(error),
+      });
+    }
   }
   throw new Error(message);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@review/agent.ts` around lines 115 - 127, In failReviewRun, isolate GitHub and
Slack notification failures by wrapping the ctx.github.comment(...) call and the
ctx.slack.post(...) call in separate try/catch blocks so one exception doesn't
prevent the other from running; catch and log each error (use the existing
logger available in the function, e.g. ctx.logger.error or processLogger.error)
and continue, ensuring you still compute channel via input(ctx, 'SLACK_CHANNEL')
and use the same message and reason variables when sending notifications.

@cubic-dev-ai cubic-dev-ai Bot 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.

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="review/agent.ts">

<violation number="1" location="review/agent.ts:116">
P2: GitHub failure comment can abort whole failure path. Catch this call so Slack alert still runs.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread review/agent.ts
reason,
});
if (ctx.github?.comment) {
await ctx.github.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.

P2: GitHub failure comment can abort whole failure path. Catch this call so Slack alert still runs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At review/agent.ts, line 116:

<comment>GitHub failure comment can abort whole failure path. Catch this call so Slack alert still runs.</comment>

<file context>
@@ -92,6 +100,34 @@ async function reviewAndFix(ctx: WorkforceCtx, pr: Pr): Promise<void> {
+    reason,
+  });
+  if (ctx.github?.comment) {
+    await ctx.github.comment(
+      { owner: pr.owner, repo: pr.repo, number: pr.number },
+      message,
</file context>

@khaliqgant khaliqgant merged commit 82e776f into main May 28, 2026
2 checks passed
@khaliqgant khaliqgant deleted the fix/pr-reviewer-fail-loud-harness branch May 28, 2026 20:59
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