fix(seer): Route coding agent handoff CTA through seer/settings/#117622
Merged
Conversation
279bd43 to
e003e15
Compare
Contributor
📊 Type Coverage Diff
🔍 4 new type safety issues introducedType assertions (
This is informational only and does not block the PR. |
e003e15 to
9fd4f88
Compare
1b2a373 to
92420b3
Compare
92420b3 to
04d8646
Compare
Base automatically changed from
billy/fix-seer-stopping-point-settings-endpoint
to
master
June 17, 2026 23:04
9fd4f88 to
54c2332
Compare
…ings/
handleStoppingPointChange, handleAutoCreatePrChange, and
handleIntegrationChange in ProjectSeerGeneralForm all called
useUpdateProjectSeerPreferences, which POSTs to the legacy
preferences endpoint. That endpoint looks up repos by
provider/owner/name and strips whitespace — the same bug that breaks
GitLab repo names — so any time a user on a GitLab org changed their
stopping point or coding agent, the request would fail with
{"detail": "Invalid repository"} (HTTP 400).
Fix by introducing useUpdateSeerSettings, which writes to the dedicated
PUT .../seer/settings/ endpoint. That endpoint accepts agent,
integrationId, stoppingPoint, and autoCreatePr with no repository
involvement, so the whitespace bug cannot be triggered.
Payload mapping per handler:
- cursor_handoff / claude_handoff: agent + integrationId + stoppingPoint + autoCreatePr
- plain stopping point: agent='seer' + stoppingPoint
- auto-create PR toggle: agent + integrationId + autoCreatePr
- integration switch: agent + new integrationId + autoCreatePr
This is the companion fix to #117518, which wired the repo add/delete
write path through PUT .../seer/repos/.
Fixes #117489
---
[View Session in Sentry](https://sentry.sentry.io/traces/?project=4510944073809921&query=gen_ai.conversation.id%3A%22slack%3AC0AKG192UP3%3A1781237406.446129%22)
Co-Authored-By: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-Authored-By: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
…Seer Replace the project-scoped useProjectSeerPreferences read and the useUpdateSeerSettings mutation in the project Seer settings page with the shared getInfiniteSeerProjectsSettingsQueryOptions and getMutateSeerProjectSettingsOptions. This routes reads and writes through the same query cache as the bulk/table views so optimistic updates stay consistent, and removes the now-unused useUpdateSeerSettings hook.
Drop the useMemo that translated SeerProjectSettingResponse into the legacy ProjectSeerPreferences shape and read the setting fields directly in the projectSeer form. This removes a lossy id round-trip (Number then String) and a fabricated preferences object, leaving a single source of truth.
The Cursor/Claude integration CTA's "Set Seer to hand off" button wrote
through the legacy `POST seer/preferences/` endpoint, which looks up repos
by `(provider, owner, name, external_id)` and strips whitespace during the
lookup. For GitLab orgs with spaces in repo names this returned
`{"detail": "Invalid repository"}` (HTTP 400) — even though the CTA only
sets up handoff and re-sent the existing repos purely to preserve them.
Switch the write to `useUpdateSeerSettings` (`PUT seer/settings/`), which
derives the handoff config server-side from agent + stopping point +
autoCreatePr and never touches repository associations. The defensive repo
re-send is dropped.
Follows the same pattern as #117518 and #117526.
Refs #117489
…hook Replace the custom useUpdateSeerSettings hook with the shared getMutateSeerProjectSettingsOptions from seerProjectSettings.ts, following conventions established in #117526. - Delete useUpdateSeerSettings.ts (duplicated logic with worse cache management: invalidated the legacy preferences query instead of the seer settings query, and had no optimistic updates) - Add autoCreatePr?: boolean to SeerProjectSettingUpdatePayload so it flows through getMutateSeerProjectSettingsOptions's ...rest spread - Update codingAgentIntegrationCta.tsx to use getMutateSeerProjectSettingsOptions + knownAgentIntegrationsQueryOptions (same endpoint as old query, just maps providers to CodingAgentProvider) - Update index.tsx similarly; filter integrations from AgentIntegration[] directly instead of using organizationIntegrationsCodingAgents - Use agentOption provider::id string format throughout - Update test expectations: integrationId is now a string, and automationTuning: medium is added when stoppingPoint is set Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54c2332 to
4132f10
Compare
Member
Author
|
@sentry review |
The coding-agent CTA now reads handoff state from seer/settings/ instead of seer/preferences/. Only fetch the per-project setting once an integration exists, since without one the CTA short-circuits to the install card — this avoids a wasted request and keeps the install-stage tests mock-free. Migrate the CTA and projectSeer specs to mock GET seer/settings/ (keyed on `agent`) instead of the now-unused seer/preferences/ + automation_handoff.
Member
Author
|
I'm not exactly sure how to test the cta but the settings works |
Co-Authored-By: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
…API states" This reverts commit c69e7f9. Co-Authored-By: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
ryan953
approved these changes
Jun 18, 2026
ryan953
reviewed
Jun 18, 2026
| organization, | ||
| project, | ||
| queryClient, | ||
| knownAgents: knownAgents ?? [], |
Member
There was a problem hiding this comment.
this should take undefined afaik
Suggested change
| knownAgents: knownAgents ?? [], | |
| knownAgents: knownAgents, |
ryan953
reviewed
Jun 18, 2026
…ts arg Address review feedback on #117622. Restore the isKnownAgentsPending flag in ProjectSeer settings so the integration, auto-create-PR, and stopping-point fields stay disabled until known agents have loaded. Without it, changing the stopping point before the integrations resolve would let parseAgentOption fall back to 'seer' and silently reset the configured handoff agent. Pass knownAgents through directly instead of defaulting to an empty array, since getMutateSeerProjectSettingsOptions already accepts undefined. Refs #117489 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Problem
The Cursor/Claude coding agent integration CTA (
codingAgentIntegrationCta.tsx, used byCursorIntegrationCtaandClaudeCodeIntegrationCtaon the project Seer settings page) wired its "Set Seer to hand off to …" button through the legacyPOST .../seer/preferences/endpoint viauseUpdateProjectSeerPreferences.That endpoint looks up repos by
(provider, owner, name, external_id)and strips whitespace fromowner/name. For GitLab orgs with spaces in repo names (e.g."My Group / My Repo"), every handoff setup returned{"detail": "Invalid repository"}(HTTP 400) — even though the CTA isn't editing repos. It only re-sent the existingrepositoriesto preserve them through the coupled legacy payload.Fix
Switch the write to
useUpdateSeerSettings(PUT .../seer/settings/), which acceptsagent,integrationId,stoppingPoint, andautoCreatePrwith no repository lookup, making it immune to the whitespace bug. The defensive repo re-send is dropped since the settings endpoint never touches repository associations.Payload mapping for handoff setup:
This matches the handoff mapping established in #117526 for
ProjectSeerGeneralForm.Scope
Only the CTA's handoff write changes. The
useProjectSeerPreferencesread (used for theisConfiguredcheck) and theuseUpdateProjectautomation-enable call are unchanged.Tests
Updated
cursorIntegrationCta.spec.tsxandclaudeCodeIntegrationCta.spec.tsxso the handoff-setup tests assertPUT .../seer/settings/with the new payload instead ofPOST .../seer/preferences/. The read-side preferences mocks are unchanged.Stacking
Stacked on #117526 (which introduces
useUpdateSeerSettings). Merge that first.Refs #117489
Fixes https://linear.app/getsentry/issue/CW-1527/failed-to-launch-coding-agent-with-anthropic-api-key