From 571eae04b48618b1db33cb09389721be963219bf Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 20 Apr 2026 07:48:10 -0500 Subject: [PATCH] Fix conference room crash from query key collision with IssueDetail ConferenceRoom used useQuery on the same queryKeys.issues.comments() key that IssueDetail uses with useInfiniteQuery. When LiveUpdatesProvider wrote InfiniteData to that shared key, ConferenceRoom received an object instead of an array, crashing on spread. Added a dedicated queryKeys.conferenceRoom.comments() key so the two caches are isolated. Co-Authored-By: Paperclip --- ui/src/context/LiveUpdatesProvider.tsx | 1 + ui/src/lib/queryKeys.ts | 1 + ui/src/pages/ConferenceRoom.tsx | 10 +++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/src/context/LiveUpdatesProvider.tsx b/ui/src/context/LiveUpdatesProvider.tsx index 84a2c3f00c6..0a7f16b85a6 100644 --- a/ui/src/context/LiveUpdatesProvider.tsx +++ b/ui/src/context/LiveUpdatesProvider.tsx @@ -686,6 +686,7 @@ function invalidateActivityQueries( queryClient.invalidateQueries({ queryKey: queryKeys.issues.activity(ref), ...invalidationOptions }); if (action === "issue.comment_added") { queryClient.invalidateQueries({ queryKey: queryKeys.issues.comments(ref), ...invalidationOptions }); + queryClient.invalidateQueries({ queryKey: queryKeys.conferenceRoom.comments(ref), ...invalidationOptions }); } if (action?.startsWith("issue.thread_interaction_")) { queryClient.invalidateQueries({ queryKey: queryKeys.issues.interactions(ref), ...invalidationOptions }); diff --git a/ui/src/lib/queryKeys.ts b/ui/src/lib/queryKeys.ts index 453dea9507e..17e0ed30875 100644 --- a/ui/src/lib/queryKeys.ts +++ b/ui/src/lib/queryKeys.ts @@ -67,6 +67,7 @@ export const queryKeys = { target: (companyId: string) => ["conference-room", companyId, "target"] as const, chats: (companyId: string, targetAgentId?: string | null) => ["conference-room", companyId, "chats", targetAgentId ?? "__default__"] as const, + comments: (issueRef: string) => ["conference-room", "comments", issueRef] as const, }, routines: { list: (companyId: string) => ["routines", companyId] as const, diff --git a/ui/src/pages/ConferenceRoom.tsx b/ui/src/pages/ConferenceRoom.tsx index d34bcdebfdd..f8bb648140c 100644 --- a/ui/src/pages/ConferenceRoom.tsx +++ b/ui/src/pages/ConferenceRoom.tsx @@ -128,7 +128,7 @@ export function ConferenceRoom() { const issueQueryRef = chatRef && chatRef !== "new" && !isHistoryRoute ? chatRef : (issueId ?? "conference-room-new"); const { data: comments = [] } = useQuery({ - queryKey: issueId ? queryKeys.issues.comments(issueQueryRef) : ["issues", "comments", "conference-room-new"], + queryKey: issueId ? queryKeys.conferenceRoom.comments(issueQueryRef) : ["conference-room", "comments", "new"], queryFn: () => issuesApi.listComments(issueId!, { order: "asc", limit: 200 }), enabled: !!issueId, }); @@ -182,7 +182,7 @@ export function ConferenceRoom() { const refs = new Set([nextIssueId, nextIdentifier, chatRef, issueId].filter(Boolean) as string[]); for (const ref of refs) { queryClient.invalidateQueries({ queryKey: queryKeys.issues.detail(ref) }); - queryClient.invalidateQueries({ queryKey: queryKeys.issues.comments(ref) }); + queryClient.invalidateQueries({ queryKey: queryKeys.conferenceRoom.comments(ref) }); queryClient.invalidateQueries({ queryKey: queryKeys.issues.runs(ref) }); queryClient.invalidateQueries({ queryKey: queryKeys.issues.liveRuns(ref) }); queryClient.invalidateQueries({ queryKey: queryKeys.issues.activeRun(ref) }); @@ -201,9 +201,9 @@ export function ConferenceRoom() { queryClient.setQueryData(queryKeys.issues.detail(nextIssue.identifier), nextIssue); } if (comment) { - queryClient.setQueryData(queryKeys.issues.comments(nextIssue.id), [comment]); + queryClient.setQueryData(queryKeys.conferenceRoom.comments(nextIssue.id), [comment]); if (nextIssue.identifier) { - queryClient.setQueryData(queryKeys.issues.comments(nextIssue.identifier), [comment]); + queryClient.setQueryData(queryKeys.conferenceRoom.comments(nextIssue.identifier), [comment]); } } invalidateConferenceRoom(nextIssue.id, nextIssue.identifier); @@ -240,7 +240,7 @@ export function ConferenceRoom() { if (context?.optimisticId) { setOptimisticComments((current) => current.filter((entry) => entry.clientId !== context.optimisticId)); } - queryClient.setQueryData(queryKeys.issues.comments(issueQueryRef), (current) => { + queryClient.setQueryData(queryKeys.conferenceRoom.comments(issueQueryRef), (current) => { const existing = current ?? []; if (existing.some((entry) => entry.id === comment.id)) return existing; return [...existing, comment].sort(