Skip to content

evals: contain the GitHub Checks availability read in a boundary - #3873

Merged
ignaciojimenezr merged 2 commits into
mainfrom
fix/evals-github-checks-error-boundary
Aug 11, 2026
Merged

evals: contain the GitHub Checks availability read in a boundary#3873
ignaciojimenezr merged 2 commits into
mainfrom
fix/evals-github-checks-error-boundary

Conversation

@ZeHuari

@ZeHuari ZeHuari commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

The bug

Sentry, prod, release 2.35.0, first seen ~3h after that release: 9 events / 4 users, all on /evals/suite/<id>, all the same shape.

Error: [CONVEX Q(github/checkRepoConfigs:getGithubChecksSettingsAvailability)] Server Error
  Called by client
  at useGithubChecksAvailability (client/src/hooks/useGithubChecksSettings.ts:75)
  at SuiteIterationsView (client/src/components/evals/suite-iterations-view.tsx:713)

The users lose the whole evals suite page — the global boundary catches it and swaps the page for an error state.

Why it throws

getGithubChecksSettingsAvailability is a signedInQuery that runs requireOrgRole(..., 'member') before it answers. It refuses rather than answers for a caller it will not serve, and that refusal is deliberate, documented backend behaviour: answering disabled to a non-member would confirm the org exists. Three ordinary situations produce a throw:

  • a guest actor — signedInQuery rejects guests at the boundary
  • a caller who is not a member of the org that was passed
  • the backend function not being deployed yet, since the two repos release independently

The org id in question comes from useEvalTabContextscopedProject?.organizationId, i.e. the project's org as held in client state, so a stale or mismatched value lands in the same throw.

The message reads only Server Error because Convex scrubs non-ConvexError messages in production. The PostHog path is not involved: isOrganizationFlagEnabled catches everything and returns false.

The backend is correct here and is unchanged by this PR.

Why it crashed the page

useQuery re-throws query errors during render, so a hook called in SuiteIterationsView itself fails the whole subtree. The hook's own docstring already said callers must treat a throw as "unavailable" and wrap it in an ErrorBoundary — and the two settings call sites (IntegrationsRoute, GithubChecksRoute) do exactly that. The call site added to the suite settings sheet in #3745 did not, which is why Sentry's suspect commit is right even though the crash only started with the 2.35.0 release.

The fix

Move the availability read out of SuiteIterationsView and into a new SuiteGithubChecksSettingsSection, which owns the section chrome as well, and wrap that component in <ErrorBoundary name="suite_github_checks" fallback={null}>.

A refused beta gate now means "no section", never "no page". The boundary still reports to Sentry (reportBoundaryError runs regardless of which fallback renders), so nothing is lost from telemetry — the errors will keep arriving, now tagged react_boundary:suite_github_checks and no longer taking a page down. That is also how we will confirm which of the three refusals these four users are hitting; the Convex prod logs for the request ids carry the real message.

Also updates the hook's docstring: the boundary is a requirement of every call site, not defence in depth, and the previously named call sites had been renamed.

Tests

New client/src/components/evals/__tests__/suite-iterations-github-checks.test.tsx — four cases over the suite settings sheet:

  • availability read throws → sibling sections still render, GitHub Checks section is gone (the regression)
  • availability read throws → still reported to the error sinks, tagged suite_github_checks
  • backend answers disabled → section hidden, nothing reported
  • backend answers enabled → section renders

Existing suite-iterations-master-detail, suite-github-checks-section and components/settings suites pass unchanged (55 tests). tsc --noEmit clean for the touched files.

🤖 Generated with Claude Code


Summary by cubic

Prevents the evals suite page from crashing by isolating the GitHub Checks availability read inside a section wrapped in an error boundary. The boundary is now keyed by org id so stale org state doesn’t hide the section for the whole session.

  • Bug Fixes
    • Moved the availability read into SuiteGithubChecksSettingsSection and wrapped it with <ErrorBoundary name="suite_github_checks" fallback={null}>; returns null when unavailable.
    • Keyed the boundary by organization id to remount on org changes and re-check availability.
    • Errors still report to Sentry with the suite_github_checks tag; only the section is suppressed.
    • Updated useGithubChecksAvailability docs to require a boundary at every call site; tests cover enabled/disabled/throw and silence boundary logs.

Written for commit e8af2ca. Summary will update on new commits.

Review in cubic

`useGithubChecksAvailability` throws by design — the backend refuses,
rather than answers, for a caller it will not serve. The suite settings
sheet called it directly in `SuiteIterationsView`, so every refusal took
the whole /evals suite page down instead of hiding one section.

Move the read into `SuiteGithubChecksSettingsSection`, which owns the
section chrome too, and wrap it in `ErrorBoundary fallback={null}`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ZeHuari
ZeHuari temporarily deployed to preview-pr-3873 August 11, 2026 00:59 — with GitHub Actions Inactive
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels Aug 11, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@chelojimenez

chelojimenez commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2389857e-0804-4fd7-9199-b2f2fc5f07a6

📥 Commits

Reviewing files that changed from the base of the PR and between 3f52576 and e8af2ca.

📒 Files selected for processing (2)
  • mcpjam-inspector/client/src/components/evals/__tests__/suite-iterations-github-checks.test.tsx
  • mcpjam-inspector/client/src/components/evals/suite-iterations-view.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • mcpjam-inspector/client/src/components/evals/suite-iterations-view.tsx
  • mcpjam-inspector/client/src/components/evals/tests/suite-iterations-github-checks.test.tsx

Walkthrough

SuiteIterationsView now renders GitHub Checks settings through a backend-gated component inside an ErrorBoundary. Availability errors hide only the GitHub Checks section and preserve the settings sheet. The hook documentation lists throwing conditions and required boundary coverage. New tests verify error reporting and rendering for error, disabled, and enabled availability responses.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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
`@mcpjam-inspector/client/src/components/evals/__tests__/suite-iterations-github-checks.test.tsx`:
- Around line 90-118: The renderSettingsSheet helper currently hardcodes an
organization identifier, so it does not cover missing values. Update
renderSettingsSheet to accept and pass an optional organizationId, then add null
and empty-string test cases verifying the settings sheet remains visible, GitHub
Checks stays hidden, and no boundary error is reported while preserving the
existing valid-identifier coverage.

In `@mcpjam-inspector/client/src/components/evals/suite-iterations-view.tsx`:
- Around line 1653-1659: Reset the suite_github_checks ErrorBoundary when
organizationId changes by keying it with organizationId or using the component’s
reset-key support, so SuiteGithubChecksSettingsSection remounts after a rejected
organization becomes valid. Add a regression test covering that organization
transition while SuiteIterationsView remains mounted.
🪄 Autofix

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: 26a3f7e1-f253-4574-975b-f99135d231c6

📥 Commits

Reviewing files that changed from the base of the PR and between 6353d58 and 3f52576.

📒 Files selected for processing (3)
  • mcpjam-inspector/client/src/components/evals/__tests__/suite-iterations-github-checks.test.tsx
  • mcpjam-inspector/client/src/components/evals/suite-iterations-view.tsx
  • mcpjam-inspector/client/src/hooks/useGithubChecksSettings.ts

Comment on lines +90 to +118
function renderSettingsSheet() {
return render(
<SuiteIterationsView
suite={baseSuite}
cases={[]}
iterations={[]}
allIterations={[]}
runs={[]}
runsLoading={false}
aggregate={null}
onRerun={vi.fn()}
onCancelRun={vi.fn()}
onDelete={vi.fn()}
onDeleteRun={vi.fn()}
onDirectDeleteRun={vi.fn().mockResolvedValue(undefined)}
connectedServerNames={new Set()}
canDeleteSuite
rerunningSuiteId={null}
cancellingRunId={null}
deletingSuiteId={null}
deletingRunId={null}
availableModels={[]}
organizationId="org-1"
projectId="project-1"
route={{ type: "suite-edit", suiteId: "suite-1" }}
navigation={noopNav}
/>
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Cover missing organization identifiers.

organizationId is optional, but renderSettingsSheet always passes "org-1". Make the helper accept an organization identifier. Add null and empty-string cases. Verify that the settings sheet remains visible, GitHub Checks stays hidden, and no boundary error is reported.

As per coding guidelines, “Tests should cover the happy path, validation errors, error handling, and edge cases such as null or empty values.”

🤖 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
`@mcpjam-inspector/client/src/components/evals/__tests__/suite-iterations-github-checks.test.tsx`
around lines 90 - 118, The renderSettingsSheet helper currently hardcodes an
organization identifier, so it does not cover missing values. Update
renderSettingsSheet to accept and pass an optional organizationId, then add null
and empty-string test cases verifying the settings sheet remains visible, GitHub
Checks stays hidden, and no boundary error is reported while preserving the
existing valid-identifier coverage.

Source: Coding guidelines

Comment thread mcpjam-inspector/client/src/components/evals/suite-iterations-view.tsx Outdated
@github-actions

github-actions Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Internal preview

Preview URL: https://mcp-inspector-pr-3873.up.railway.app
Deployed commit: 8d30196
PR head commit: e8af2ca
Backend target: staging fallback.
Health: ✅ Convex reachable
Access is employee-only in non-production environments.

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

All reported issues were addressed across 3 files

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

Re-trigger cubic

Comment thread mcpjam-inspector/client/src/components/evals/suite-iterations-view.tsx Outdated
Two review findings on the boundary added here:

The boundary holds its error state forever once tripped, and `fallback={null}`
exposes no reset. The org id comes from client state, so the exact failure this
PR handles — a stale org id — would hide the section for the rest of the
session even after the id corrects itself. Keying the boundary by org id
remounts it when the id changes, which re-asks availability.

The two throwing tests exercise the real componentDidCatch, which logs the full
error and component stack on every passing run. Silenced via a console.error
spy, restored after each case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dosubot dosubot Bot removed the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 11, 2026
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Aug 11, 2026
@ignaciojimenezr
ignaciojimenezr merged commit de74d6f into main Aug 11, 2026
12 checks passed
@ignaciojimenezr
ignaciojimenezr deleted the fix/evals-github-checks-error-boundary branch August 11, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants