Conversation
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛
Internal Changes 🔧Release
Other
🤖 This preview updates automatically when you update the PR. |
| headers: { | ||
| ...init.headers, | ||
| ...bearer, | ||
| ...csrf, |
There was a problem hiding this comment.
Undefined variable csrf causes runtime error
High Severity
The variable csrf is referenced in the headers object on line 101 (...csrf), but its declaration on line 94 is commented out. This causes a ReferenceError: csrf is not defined when fetchProxy is invoked, breaking all API calls made through the toolbar's fetch proxy.
Additional Locations (1)
| isSubmitting, | ||
| }: PendingUserInputProps) { | ||
| const [selectedAnswers, setSelectedAnswers] = useState<Record<string, string>>({}); | ||
| const [selectedPatches, setSelectedPatches] = useState<number[]>([]); |
There was a problem hiding this comment.
Stale selection state persists across different pending inputs
Medium Severity
The selectedPatches and selectedAnswers state in PendingUserInput is initialized once and never resets when the pendingInput prop changes. Since no key prop is provided when rendering the component, React reuses the same instance. This causes stale selections to carry over between different pending inputs — the "Approve Selected" button may display an incorrect count, and invalid patch indices may be submitted to the server.
Additional Locations (1)
| const [{organizationSlug}] = useConfigContext(); | ||
| const {fetchFn} = useSentryApi<SeerExplorerSessionResponse>(); | ||
| const pollingStartTimeRef = useRef<number | null>(null); | ||
| const pollCountRef = useRef<number>(0); |
There was a problem hiding this comment.
Polling timeout refs persist incorrectly across session changes
Medium Severity
The pollingStartTimeRef and pollCountRef refs in useSeerExplorerSession persist across runId changes. When a user switches from one actively-polling session to another, the 5-minute timeout continues from where the previous session left off rather than resetting. This can cause polling to stop prematurely for the new session, leaving users with stale data.
| queryClient.invalidateQueries({ | ||
| queryKey: [`/organizations/${organizationSlug}/seer/explorer-chat/`], | ||
| }); | ||
| }, |
There was a problem hiding this comment.
Session query not invalidated when continuing existing chat
Medium Severity
The onSuccess handler in useSeerExplorerChat invalidates queries with key ['/organizations/.../seer/explorer-chat/'], but when continuing an existing chat, the session query uses key ['/organizations/.../seer/explorer-chat/${runId}/']. These keys don't match, so the session query isn't invalidated. When a user sends a message to an existing session, the UI won't update immediately — the sent message only appears after polling kicks in, causing a noticeable delay.
Add access control for the Seer Explorer panel based on organization feature flags. The panel is only shown when the organization has both `seer-explorer` and either `seer-billing` or `seat-based-seer-enabled`. - Add useSeerExplorerAccess hook to check feature flag access - Hide nav button when user lacks access - Add RequireSeerExplorer route guard to prevent direct URL access
| {query: inputValue, runId: currentRunId}, | ||
| { | ||
| onSuccess: data => { | ||
| const newRunId = data.json.run_id; |
There was a problem hiding this comment.
Bug: The onSuccess callback accesses data.json.run_id without checking if data.json is defined, which can be undefined if the API response body fails to parse.
Severity: MEDIUM
Suggested Fix
Add a check in the onSuccess callback to ensure data.json is not undefined before accessing its properties. Optional chaining (data.json?.run_id) can be used for a concise and safe access pattern.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/lib/components/panels/seerExplorer/SeerExplorerPanel.tsx#L58
Potential issue: The `onSuccess` callback for the `sendMessage` mutation in
`SeerExplorerPanel.tsx` directly accesses `data.json.run_id`. The underlying
`useSentryApi` hook uses `tryJsonParse`, which returns `undefined` if the API response
body is not valid JSON. However, the hook does not throw an error for JSON parsing
failures on successful HTTP status codes (e.g., 200 OK). If the API returns a 200 OK
response with a malformed or non-JSON body, `data.json` will be `undefined`, causing a
`TypeError` when the code attempts to access `data.json.run_id`.
Did we get this right? 👍 / 👎 to inform future reviews.
| const [selectedAnswers, setSelectedAnswers] = useState<Record<string, string>>({}); | ||
| const [selectedPatches, setSelectedPatches] = useState<number[]>([]); |
There was a problem hiding this comment.
Bug: The PendingUserInput component lacks a key prop. Its internal state will persist across different user prompts, potentially causing stale data to be submitted.
Severity: MEDIUM
Suggested Fix
In SeerExplorerPanel.tsx, add a unique key prop to the PendingUserInput component, using the ID of the pending input. For example: <PendingUserInput key={session.pending_user_input.id} ... />. This will ensure React remounts the component with fresh state whenever the pending input changes.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/lib/components/panels/seerExplorer/PendingUserInput.tsx#L22-L23
Potential issue: The `PendingUserInput` component is rendered without a unique `key`
prop. When the `session.pending_user_input` data is updated after a user submission,
React will reuse the existing component instance instead of mounting a new one. This
causes the component's internal state (e.g., `selectedAnswers`) to persist from the
previous prompt. If a user is presented with a sequence of questions, the state from the
first question could be incorrectly submitted as part of the response to the second
question, leading to incorrect behavior or data corruption.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| queryClient.invalidateQueries({ | ||
| queryKey: [`/organizations/${organizationSlug}/seer/explorer-chat/`], | ||
| }); | ||
| }, |
There was a problem hiding this comment.
Runs list not invalidated after creating new session
Low Severity
The onSuccess callback in useSeerExplorerChat only invalidates session queries (/seer/explorer-chat/) but not the runs query (/seer/explorer-runs/). When a user creates a new session and then opens the History panel, the newly created session won't appear in the list until a refetch is triggered by window focus or navigation.
This is a first-draft to get Seer Explorer output into the toolbar.