Repository navigation
feat(seer-billing): Handle SeerOutOfCreditsException at Autofix callers - #130284
Merged
Merged
Conversation
Return a 402 before sending a chat message when a token-billed org does not have enough Seer credits. Dashboard generation runs are not gated. can_run_seer_operation now passes orgs that are not token-billed. Refs CW-3061
Token-billed orgs are checked for Seer credits before each Autofix step and before opening a PR, and get SeerOutOfCreditsException when they can't pay. Other orgs keep the seat-based quota check. Agentic triage runs are not gated. Refs CW-3061
The issue page returns a 402, Slack shows an error, the admin endpoints report it, and automatic paths (new issue automation, completion hook, PR iteration) log and stop. Refs CW-3061
Autofix billing checks the token-billed flag itself, so it only needs the credit check.
…1-autofix-out-of-credits
…tofix-gating # Conflicts: # src/sentry/seer/credits.py
…1-autofix-out-of-credits
Contributor
Sentry Snapshot Testing
|
…gent-chat # Conflicts: # src/sentry/seer/endpoints/organization_seer_agent_chat.py
…tofix-gating # Conflicts: # src/sentry/seer/autofix/feature/dispatch.py # tests/sentry/seer/autofix/feature/test_dispatch.py
…1-autofix-out-of-credits # Conflicts: # src/sentry/seer/endpoints/group_ai_autofix.py
Chat replies to single runs continue the run through continue_single_run, which skipped billing. The run's own referrer decides, so agentic triage runs stay free.
…1-autofix-out-of-credits
…gent-chat # Conflicts: # src/sentry/seer/endpoints/organization_seer_agent_chat.py
…tofix-gating Check the credit check flag before the token-billed flag. has_enough_seer_credits no longer checks the flag; its callers do.
…1-autofix-out-of-credits # Conflicts: # src/sentry/seer/entrypoints/operator.py # tests/sentry/seer/endpoints/test_group_ai_autofix.py
Cover orgs that aren't token-billed, group the chat credit tests after the access tests, and match the neighboring tests' names and setup.
…1-autofix-out-of-credits
…utofix-gating # Conflicts: # src/sentry/seer/credits.py
Single runs are behind organizations:autofix-single-run and need their own estimate, so they're out of scope here.
billyvg
reviewed
Nov 9, 2026
billyvg
approved these changes
Nov 9, 2026
trigger_autofix_agent checked billing, then called trigger_autofix_feature, which checked it again with the same arguments. Keep only the dispatch check, and test a token-billed org with credit checks off.
srest2021
added a commit
that referenced
this pull request
Nov 9, 2026
…tion (#130463) relates to CW-2332 depends on #129563, #130283, #130284 The chat's credit check only runs when the panel opens or the window regains focus. If credits run out partway through a conversation, the message box stays enabled and the next send fails with a generic error. This rechecks credits when: - Seer stops a reply for credits (`failure_reason: out_of_credits`) - a send comes back 402 so the out-of-credits notice and disabled message box show right away. A 402 no longer shows "There was an error sending your message"; the recheck brings up the notice instead. The recheck invalidates the credit check query, like `useExplorerAutofix` does. That needed `useSeerCreditCheck` to turn off with `enabled` instead of `skipToken`, so the key is the same either way. Example (it would show any intermediate thinking as well): <img width="402" height="615" alt="× Seer Agent I" src="https://github.com/user-attachments/assets/c7e056e8-73a7-4a5a-be32-62bcb80e1609" /> --------- Co-authored-by: Billy Vong <billy@sentry.io> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
alexsohn1126
approved these changes
Nov 9, 2026
| self.entrypoint.on_trigger_autofix_error(error=error) | ||
| lifecycle.record_failure(failure_reason=error) | ||
| return | ||
| except SeerOutOfCreditsException: |
Member
There was a problem hiding this comment.
I've cut out CW-3080 to track the work to post richer replies for this case. Thanks!
Credit checks no longer skip runs by referrer. Agentic triage runs are checked like any other until a follow-up marks them by feature instead. Credit checks are behind seer-credit-checks, so nothing changes in production. Refs CW-3061
…' into srest2021/CW-3061-autofix-out-of-credits
jaydgoss
reviewed
Nov 10, 2026
…402s Add a stable code to each billing 402 body (seer_out_of_credits, seer_out_of_quota) so API clients like the CLI and MCP can branch on it instead of the detail text. The out-of-quota response becomes a dict with detail and code instead of a bare string. Co-Authored-By: Sofia Rest <sofia.rest@sentry.io>
An operation only sets the credit estimate, since it can run under more than one feature, so callers pass the feature explicitly. The credit check endpoint now takes a feature param.
The UI can't tell runs agentic triage started apart yet, so the credit check endpoint picks the feature itself instead of requiring the UI to send it.
…' into srest2021/CW-3061-autofix-out-of-credits
srest2021
added a commit
that referenced
this pull request
Nov 10, 2026
…130283) Relates to CW-3061 Adds `check_autofix_billing`, called from all autofix entrypoints: `trigger_autofix_agent`, `trigger_autofix_feature`, `trigger_push_changes` and `continue_single_run`. - Token-billed orgs are checked for credits before every step, before Open PR and before a reply to a single run, and get `SeerOutOfCreditsException` if they can't pay. All credit checks are also separately feature-flagged. - Other orgs keep the same quota check. Autofix single run replies get their own billable operation with a placeholder estimate. WIP followup to handle the out of credits exceptions: #130284 --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
…-credits' into srest2021/CW-3061-autofix-out-of-credits
BYK
pushed a commit
to getsentry/toolkit
that referenced
this pull request
Nov 11, 2026
`sentry issue explain` and `sentry issue plan` treat every 402 from the autofix endpoint as "Seer requires a paid plan" and offer a free trial. An org on token-based billing that runs out of Seer credits gets that message too. A run that starts and then stops for credits reads as "Analysis completed but no root causes found" or "Plan creation failed". - A 402 with `code: "seer_out_of_credits"` (added in getsentry/sentry#130284) now raises a new `out_of_credits` Seer error. Any other 402, including `seer_out_of_quota` and the 402 with no code that older Sentry versions send, keeps the current no-budget error. - A run that ends with `failure_reason: "out_of_credits"` raises the same error from both commands. - The error has its own exit code, 43, and is left out of the free trial prompt. What the user sees: ``` Your organization is out of Seer credits. Someone with billing access can adjust Seer spend and auto-reload in Sentry: https://my-org.sentry.io/settings/billing/overview/?product=seer ``` A failed run is still retried on the next invocation, so someone who topped up recovers by running the command again. The 402 comes from getsentry/sentry#130283 and getsentry/sentry#130284, which have both merged. Sentry's credit checks are behind the `organizations:seer-credit-checks` flag, so for an org without it the CLI behaves as it does today. The MCP equivalent is #2031. Fixes CW-3075
srest2021
added a commit
to getsentry/toolkit
that referenced
this pull request
Nov 11, 2026
Fixes CW-2330 Depends on getsentry/sentry#130284 `analyze_issue_with_seer` now says why a run didn't start when Sentry answers 402, for out-of-credits and out-of-quota orgs, instead of returning an API error. It tells the two apart by `code`. A 402 without the out-of-credits code, including the bare-string out-of-quota body that Sentry sends before #130284, still reads as out of quota. When a run stopped because the org ran out of credits (`failure_reason=out_of_credits`), the tool and `get_issue_details` now say why. Until the Sentry PRs ship, a run that runs out of credits still starts and then stops with `out_of_credits`, which this PR already explains. Both Sentry checks are behind `organizations:seer-credit-checks`. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@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.
Fixes CW-3061
Handles the
SeerOutOfCreditsExceptionexception from #130283 at every caller. Quota is only checked when a new run starts, so "not checked" means a continuation.User triggered
Automatically triggered
push_failed, without pausing iterationNote: The PR iteration behavior doesn't have good UX yet. When a push or retry is refused for credits, the user sees nothing and the PR isn't updated. When Seer itself stops an iteration for credits, iteration on the PR is paused for good, even after a top-up. See CW-3066 for planned followup work