From 5057f14df9f43d4924f2e98cd7597dd3acb1bd58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Malfait?= Date: Thu, 2 Jul 2026 23:32:49 +0200 Subject: [PATCH] test(ai): pin the queue-updated event that now follows stream-error on the failure path (#22500) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Rationale main's `server-test` is red: 4 error-path tests in `stream-agent-chat.job.spec.ts` fail. #22494 made the stream failure path publish `queue-updated` **after** the terminal `stream-error` (so background tabs refetch the persisted partial transcript), but these specs still asserted `stream-error` is the *last* published event. Classic squash-merge semantic conflict — #22494's branch predated the spec assertions, both were green in isolation. ## Why this is the right fix (not patching a symptom) The job behavior is the intended one from #22494; the specs encode the old contract. Rather than loosening the assertions to "a stream-error was published somewhere", this pins the full intended terminal sequence — `stream-error` followed by `queue-updated` — so the convergence event itself is now regression-tested on all four failure paths (mid-stream provider error, setup rejection, persistence failure, missing workspace). ## Impact Unblocks `server-test` / `ci-server-status-check` for every open PR (including #22498, which is needed to fix the dev-cluster migration incident). Test-only change. https://claude.ai/code/session_01Lyi6zTema2FMVVh8MD6c38 --- _Generated by [Claude Code](https://claude.ai/code/session_01Lyi6zTema2FMVVh8MD6c38)_ Review in cubic --- .../__tests__/stream-agent-chat.job.spec.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/jobs/__tests__/stream-agent-chat.job.spec.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/jobs/__tests__/stream-agent-chat.job.spec.ts index 522bc79325..755a9c098f 100644 --- a/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/jobs/__tests__/stream-agent-chat.job.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-chat/jobs/__tests__/stream-agent-chat.job.spec.ts @@ -230,11 +230,14 @@ describe('StreamAgentChatJob', () => { ); expect(chunkEvents).toHaveLength(TEXT_CHUNKS.length); - expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({ type: 'stream-error', code: 'STREAM_EXECUTION_FAILED', message: 'provider exploded', }); + expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + type: 'queue-updated', + }); expect(publishedEvents.map((event) => event.type)).not.toContain( 'message-persisted', ); @@ -264,10 +267,13 @@ describe('StreamAgentChatJob', () => { 'model resolution failed', ); - expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({ type: 'stream-error', message: 'model resolution failed', }); + expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + type: 'queue-updated', + }); expect(threadRepository.update).toHaveBeenCalledWith( 'workspace-id', { id: 'thread-id', activeStreamId: 'stream-id' }, @@ -287,9 +293,12 @@ describe('StreamAgentChatJob', () => { ); expect(chunkEvents).toHaveLength(TEXT_CHUNKS.length); - expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({ type: 'stream-error', }); + expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + type: 'queue-updated', + }); expect(publishedEvents.map((event) => event.type)).not.toContain( 'message-persisted', ); @@ -304,10 +313,13 @@ describe('StreamAgentChatJob', () => { code: AiExceptionCode.WORKSPACE_NOT_FOUND, }); - expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + expect(publishedEvents[publishedEvents.length - 2]).toMatchObject({ type: 'stream-error', code: AiExceptionCode.WORKSPACE_NOT_FOUND, }); + expect(publishedEvents[publishedEvents.length - 1]).toMatchObject({ + type: 'queue-updated', + }); expect(threadRepository.update).toHaveBeenCalledWith( 'workspace-id', { id: 'thread-id' },