Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 2 additions & 16 deletions apps/sim/executor/handlers/workflow/workflow-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ describe('WorkflowBlockHandler', () => {
// Reset all mocks
vi.clearAllMocks()

// Clear the static execution stack

;(WorkflowBlockHandler as any).executionStack.clear()
// No cycle detection state to clear

// Setup default fetch mock
mockFetch.mockResolvedValue({
Expand Down Expand Up @@ -102,19 +100,7 @@ describe('WorkflowBlockHandler', () => {
)
})

it('should detect and prevent cyclic dependencies', async () => {
const inputs = { workflowId: 'child-workflow-id' }

// Simulate a cycle by adding the execution to the stack

;(WorkflowBlockHandler as any).executionStack.add(
'parent-workflow-id_sub_child-workflow-id_workflow-block-1'
)

await expect(handler.execute(mockBlock, inputs, mockContext)).rejects.toThrow(
'Error in child workflow "child-workflow-id": Cyclic workflow dependency detected: parent-workflow-id_sub_child-workflow-id_workflow-block-1'
)
})
// Cycle detection removed; relying on depth/timeout

it('should enforce maximum depth limit', async () => {
const inputs = { workflowId: 'child-workflow-id' }
Expand Down
15 changes: 1 addition & 14 deletions apps/sim/executor/handlers/workflow/workflow-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const MAX_WORKFLOW_DEPTH = 10
*/
export class WorkflowBlockHandler implements BlockHandler {
private serializer = new Serializer()
private static executionStack = new Set<string>()

canHandle(block: SerializedBlock): boolean {
return block.metadata?.id === BlockType.WORKFLOW
Expand All @@ -47,15 +46,6 @@ export class WorkflowBlockHandler implements BlockHandler {
throw new Error(`Maximum workflow nesting depth of ${MAX_WORKFLOW_DEPTH} exceeded`)
}

// Check for cycles - include block ID to differentiate parallel executions
const executionId = `${context.workflowId}_sub_${workflowId}_${block.id}`
if (WorkflowBlockHandler.executionStack.has(executionId)) {
throw new Error(`Cyclic workflow dependency detected: ${executionId}`)
}

// Add current execution to stack
WorkflowBlockHandler.executionStack.add(executionId)

// Load the child workflow from API
const childWorkflow = await this.loadChildWorkflow(workflowId)

Expand Down Expand Up @@ -102,8 +92,7 @@ export class WorkflowBlockHandler implements BlockHandler {
const result = await subExecutor.execute(workflowId)
const duration = performance.now() - startTime

// Remove current execution from stack after completion
WorkflowBlockHandler.executionStack.delete(executionId)
// No-op: execution id used only for logging
Comment thread
icecrasher321 marked this conversation as resolved.
Outdated

logger.info(`Child workflow ${childWorkflowName} completed in ${Math.round(duration)}ms`)

Expand Down Expand Up @@ -131,8 +120,6 @@ export class WorkflowBlockHandler implements BlockHandler {
} catch (error: any) {
logger.error(`Error executing child workflow ${workflowId}:`, error)

const executionId = `${context.workflowId}_sub_${workflowId}_${block.id}`
WorkflowBlockHandler.executionStack.delete(executionId)
const { workflows } = useWorkflowRegistry.getState()
const workflowMetadata = workflows[workflowId]
const childWorkflowName = workflowMetadata?.name || workflowId
Expand Down