Repository navigation
fix(mcp,cli): Explain Seer setup 409s - #2207
Merged
Merged
Conversation
Sentry refuses to start an Autofix run with a 409 and a code (scm_integration_required or repos_not_linked) when the org has no GitHub/GitLab integration or the issue's project has no linked repositories. The tool rethrew that 409, so agents saw a generic "Input Error" telling them to fix their input and retry. Return "Analysis Not Started" with Sentry's explanation instead, like the 402 out-of-credits case, and name the prerequisite in the tool hints. Other 409s still throw. Co-Authored-By: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Sentry refuses to start an Autofix run with a 409 and code scm_integration_required or repos_not_linked. The CLI passed that through as a generic ApiError (exit 30). Map both codes to SeerError, which says what's missing and links the integrations or Seer settings page, and give them exit code 44 (SEER_SETUP_REQUIRED). Other 409s, such as a run already in flight, stay ApiErrors. Co-Authored-By: Claude <noreply@anthropic.com>
…quired-409 # Conflicts: # packages/mcp-core/src/tools/catalog/analyze-issue-with-seer.test.ts
BYK
approved these changes
Nov 13, 2026
BYK
marked this pull request as ready for review
November 13, 2026 12:57
This was referenced Nov 13, 2026
BYK
added a commit
to getsentry/sentry
that referenced
this pull request
Nov 13, 2026
The OpenAPI schema for `POST
/organizations/{org}/issues/{issue_id}/autofix/`
(`startOrganizationIssueAutofix`) listed only 202, 400, 401, 403 and
404, so `@sentry/api` types every error as `unknown`. The Sentry CLI and
MCP in getsentry/toolkit map the 402 and 409 `code` values to
user-facing messages, and they hardcode those codes today because the
schema doesn't have them (see
getsentry/toolkit#2207). Requested by @BYK.
This adds typed bodies for both statuses, with `code` as an enum:
- **402** `AutofixPaymentRequiredResponse`: `detail` and a required
`code`, either `seer_out_of_credits` or `seer_out_of_quota`. Every 402
this endpoint returns sets a code: the `open_pr` and default-step credit
and quota checks, and the `pr_iteration` credit check in
`handle_ui_feedback`.
- **409** `AutofixConflictResponse`: `detail`, plus an optional `code`
(`scm_integration_required`, `repos_not_linked`, or `run_in_flight`),
and the optional `run_id` and `sentry_run_id` that come with
`run_in_flight`. `code` is optional because some 409s carry only
`detail`: re-running a step after a PR or coding agent started, paused
PR iteration, and a run that is still being created.
The codes come from `Literal` types that now back the existing constants
(`SEER_OUT_OF_CREDITS_CODE`, `SEER_OUT_OF_QUOTA_CODE`,
`RUN_IN_FLIGHT_CODE`, and the keys of `AUTOFIX_SETUP_REQUIRED_DETAIL`).
If a constant holds a code that the `Literal` doesn't list, mypy fails,
so the enum and the runtime stay in sync. This is a typing and schema
change only, with no change to runtime behavior.
The 422 that `resolve_seer_run` returns when a run failed to start is
still undocumented. I left it out to keep this change to 402 and 409.
<!-- junior-request-attribution:start -->
via @BYK.
<!-- junior-request-attribution:end -->
<!-- junior-session-footer:start -->
<!-- junior-conversation-id:agent%3A255009b50ca40a74d79e4c03aef8af92 -->
--
[View
Session](https://junior-prod.sentry.dev/conversations/agent%3A255009b50ca40a74d79e4c03aef8af92)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A255009b50ca40a74d79e4c03aef8af92/?project=4510944073809921)
<!-- junior-session-footer:end -->
Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sentry refuses to start a new Autofix run with a 409 when the org has no GitHub/GitLab integration or the issue's project has no linked repositories. The body carries a
code(scm_integration_requiredorrepos_not_linked) and adetail(sentrysrc/sentry/seer/endpoints/group_ai_autofix.py:_check_autofix_setupat :204-220, the 409 at :510-520). Orgs on the legacyseer-addedplan skip the check.This was reported through Sentry MCP user feedback: Seer analysis returned HTTP 409 requiring connected repositories, and the tool prerequisites don't mention repository connection.
MCP:
analyze_issue_with_seerThe tool handled the 402 out-of-credits case but rethrew this 409. The error handler then turned it into a generic Input Error that tells the agent to fix its input and try again (
internal/error-handling.ts:292-303). The tool description didn't mention the prerequisite either.Now the tool returns
## Analysis Not Startedwith Sentry'sdetailand says that retrying won't help until the setup is done, the same way it handles the 402. The tool hints now say that a new analysis needs an SCM integration and repositories linked to the project. Any other 409 still throws. The tool's POST sends onlyuser_context, with norun_idorstep, so it's always a kickoff, and the setup gate is the only 409 a kickoff can hit (group_ai_autofix.py:369-407 and :505-520).CLI:
issue explain/issue planBefore, the CLI passed the 409 through as a plain
ApiError, which exits with 30 and shows only Sentry's detail. NowcreateSeerErrormaps both codes to newSeerErrorreasons,scm_integration_requiredandrepos_not_linked. These say what's missing and link the page that fixes it: the source code integrations directory, or the org's Seer settings, where Sentry keeps the project-to-repo links it checks (SeerProjectRepository). Both reasons exit with a new code, 44SEER_SETUP_REQUIRED. I added it toexit-codes.mdandpackages/cli/AGENTS.md. No trial hint, since a trial doesn't fix setup. Other 409s, such asrun_in_flightfromissue plancontinuing a run, stayApiErrors.Reporting change to review: on SaaS,
SeerErroris deliberately still captured, because it feeds the Seer upsell dashboard (error-reporting.ts:186-191). These 409s were silenced before, asapi_user_error. After this PR, CLI setup 409s on SaaS show up asSeerErrorevents tagged with their reason. That fits the existing "SeerError is a product signal" rule, but it's a volume change. If you'd rather keep them silenced, add them to the silence list.Tests
explains why the run did not start when Sentry answers 409(both codes) andstill throws a 409 that is not a setup code. The new 409 cases fail without the fix. The fullmcp-corevitest run passes, and so doestsc --noEmit.createSeerErrorcases (both codes, plusrun_in_flightstaying null),SeerErrorformat and exit-code cases, and anissue explainfunc test for arepos_not_linked409. The new createSeerError and explain cases fail without the fix.tsc --noEmitpasses.npx -y sentrybecause of how the sandbox launches the CLI, plus EACCES and DNS tests). I comparedtest/commands/issue/utils.test.tswith and without the change, and the failures were identical. CI is authoritative here.pnpm run lint/test, and I didn't QA either path against a live org that has no repos linked.Heads-up: #2198 changes the same MCP handler (it restarts failed runs). The two changes don't overlap, but whichever lands second needs a rebase.
via Sentry, @BYK.
--
View Session [Sentry]