22 * @vitest -environment node
33 */
44import { resetTerminalConsoleMock , terminalConsoleMockFns } from '@sim/testing'
5- import { beforeEach , describe , expect , it , vi } from 'vitest'
5+ import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
66import {
77 addExecutionErrorConsoleEntry ,
88 addHttpErrorConsoleEntry ,
99 createBlockEventHandlers ,
10+ executeWorkflowWithFullLogging ,
1011 handleExecutionCancelledConsole ,
1112 handleExecutionErrorConsole ,
1213 reconcileFinalBlockLogs ,
1314} from '@/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-execution-utils'
1415import type { BlockLog } from '@/executor/types'
16+ import type { ExecutionStreamHttpError } from '@/hooks/use-execution-stream'
1517import { useExecutionStore } from '@/stores/execution'
1618
1719describe ( 'workflow-execution-utils' , ( ) => {
@@ -22,6 +24,43 @@ describe('workflow-execution-utils', () => {
2224 } as any )
2325 } )
2426
27+ afterEach ( ( ) => {
28+ vi . unstubAllGlobals ( )
29+ } )
30+
31+ it ( 'classifies a duplicate Copilot claim without writing an HTTP error row' , async ( ) => {
32+ vi . mocked ( useExecutionStore . getState ) . mockReturnValue ( {
33+ getCurrentExecutionId : vi . fn ( ( ) => 'exec-1' ) ,
34+ setActiveBlocks : vi . fn ( ) ,
35+ setBlockRunStatus : vi . fn ( ) ,
36+ setCurrentExecutionId : vi . fn ( ) ,
37+ setEdgeRunStatus : vi . fn ( ) ,
38+ } as any )
39+ vi . stubGlobal (
40+ 'fetch' ,
41+ vi . fn ( ) . mockResolvedValue ( {
42+ ok : false ,
43+ status : 409 ,
44+ json : vi . fn ( ) . mockResolvedValue ( {
45+ error : 'Copilot workflow tool is already bound to another execution' ,
46+ code : 'COPILOT_WORKFLOW_EXECUTION_CONFLICT' ,
47+ } ) ,
48+ } )
49+ )
50+
51+ const promise = executeWorkflowWithFullLogging ( {
52+ workflowId : 'wf-1' ,
53+ executionId : 'exec-1' ,
54+ copilotToolCallId : 'tool-1' ,
55+ } )
56+
57+ await expect ( promise ) . rejects . toMatchObject < ExecutionStreamHttpError > ( {
58+ httpStatus : 409 ,
59+ code : 'COPILOT_WORKFLOW_EXECUTION_CONFLICT' ,
60+ } )
61+ expect ( terminalConsoleMockFns . mockAddConsole ) . not . toHaveBeenCalled ( )
62+ } )
63+
2564 describe ( 'createBlockEventHandlers' , ( ) => {
2665 it ( 'skips duplicate block start rows during reconnect replay' , ( ) => {
2766 terminalConsoleMockFns . mockAddConsole ( {
0 commit comments