From 34bcef04eb7d46d69299e477c898bbd0b853e52a Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 15 Nov 2025 12:09:04 -0800 Subject: [PATCH 1/3] Fix disabled blocks --- .../hooks/use-workflow-execution.ts | 11 +++++--- apps/sim/executor/dag/construction/paths.ts | 27 +++++++++++++++++++ apps/sim/lib/workflows/triggers.ts | 5 ++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts index 1e343838322..b0f82b326c3 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts @@ -682,10 +682,10 @@ export function useWorkflowExecution() { const workflowEdges = (executionWorkflowState?.edges ?? latestWorkflowState.edges) as typeof currentWorkflow.edges - // Filter out blocks without type (these are layout-only blocks) + // Filter out blocks without type (these are layout-only blocks) and disabled blocks const validBlocks = Object.entries(workflowBlocks).reduce( (acc, [blockId, block]) => { - if (block?.type) { + if (block?.type && block.enabled !== false) { acc[blockId] = block } return acc @@ -725,13 +725,18 @@ export function useWorkflowExecution() { } }) - // Do not filter out trigger blocks; executor may need to start from them + // Filter out blocks without type and disabled blocks const filteredStates = Object.entries(mergedStates).reduce( (acc, [id, block]) => { if (!block || !block.type) { logger.warn(`Skipping block with undefined type: ${id}`, block) return acc } + // Skip disabled blocks to prevent them from being passed to executor + if (block.enabled === false) { + logger.warn(`Skipping disabled block: ${id}`) + return acc + } acc[id] = block return acc }, diff --git a/apps/sim/executor/dag/construction/paths.ts b/apps/sim/executor/dag/construction/paths.ts index 55cf559d3cb..a4ffd15ebc5 100644 --- a/apps/sim/executor/dag/construction/paths.ts +++ b/apps/sim/executor/dag/construction/paths.ts @@ -28,6 +28,25 @@ export class PathConstructor { const block = workflow.blocks.find((b) => b.id === triggerBlockId) if (block) { + // Validate that the trigger block is enabled + if (!block.enabled) { + logger.error('Provided triggerBlockId is disabled, finding alternative', { + triggerBlockId, + blockEnabled: block.enabled, + }) + // Try to find an alternative enabled trigger instead of failing + const alternativeTrigger = this.findExplicitTrigger(workflow) + if (alternativeTrigger) { + logger.info('Using alternative enabled trigger', { + disabledTriggerId: triggerBlockId, + alternativeTriggerId: alternativeTrigger, + }) + return alternativeTrigger + } + throw new Error( + `Trigger block ${triggerBlockId} is disabled and no alternative enabled trigger found` + ) + } return triggerBlockId } @@ -95,8 +114,16 @@ export class PathConstructor { private buildAdjacencyMap(workflow: SerializedWorkflow): Map { const adjacency = new Map() + // Build a set of enabled block IDs for quick lookup + const enabledBlocks = new Set(workflow.blocks.filter((b) => b.enabled).map((b) => b.id)) for (const connection of workflow.connections) { + // Only include edges where both source and target are enabled + // This prevents disabled blocks from being included in reachability + if (!enabledBlocks.has(connection.source) || !enabledBlocks.has(connection.target)) { + continue + } + const neighbors = adjacency.get(connection.source) ?? [] neighbors.push(connection.target) adjacency.set(connection.source, neighbors) diff --git a/apps/sim/lib/workflows/triggers.ts b/apps/sim/lib/workflows/triggers.ts index e5026717742..dfb5601d2c4 100644 --- a/apps/sim/lib/workflows/triggers.ts +++ b/apps/sim/lib/workflows/triggers.ts @@ -177,6 +177,11 @@ export function resolveStartCandidates( const candidates: StartBlockCandidate[] = [] for (const [blockId, block] of entries) { + // Skip disabled blocks - they cannot be used as triggers + if ('enabled' in block && block.enabled === false) { + continue + } + const path = classifyStartBlock(block) if (!path) continue From 65bacec57e6b873a435d3c27a97e6e6b8471a77f Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 15 Nov 2025 12:14:24 -0800 Subject: [PATCH 2/3] Comments --- apps/sim/executor/dag/construction/paths.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/sim/executor/dag/construction/paths.ts b/apps/sim/executor/dag/construction/paths.ts index a4ffd15ebc5..ec7ea488367 100644 --- a/apps/sim/executor/dag/construction/paths.ts +++ b/apps/sim/executor/dag/construction/paths.ts @@ -28,7 +28,6 @@ export class PathConstructor { const block = workflow.blocks.find((b) => b.id === triggerBlockId) if (block) { - // Validate that the trigger block is enabled if (!block.enabled) { logger.error('Provided triggerBlockId is disabled, finding alternative', { triggerBlockId, @@ -114,12 +113,9 @@ export class PathConstructor { private buildAdjacencyMap(workflow: SerializedWorkflow): Map { const adjacency = new Map() - // Build a set of enabled block IDs for quick lookup const enabledBlocks = new Set(workflow.blocks.filter((b) => b.enabled).map((b) => b.id)) for (const connection of workflow.connections) { - // Only include edges where both source and target are enabled - // This prevents disabled blocks from being included in reachability if (!enabledBlocks.has(connection.source) || !enabledBlocks.has(connection.target)) { continue } From e271b7fe5c133b8e2a6e8c23134b851a4322232b Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Sat, 15 Nov 2025 12:17:11 -0800 Subject: [PATCH 3/3] Fix api/chat trigger not found message --- apps/sim/lib/workflows/executor/execution-core.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/sim/lib/workflows/executor/execution-core.ts b/apps/sim/lib/workflows/executor/execution-core.ts index 08b5b60f6e8..6da23164909 100644 --- a/apps/sim/lib/workflows/executor/execution-core.ts +++ b/apps/sim/lib/workflows/executor/execution-core.ts @@ -257,12 +257,7 @@ export async function executeWorkflowCore( const startBlock = TriggerUtils.findStartBlock(mergedStates, executionKind, false) if (!startBlock) { - const errorMsg = - executionKind === 'api' - ? 'No API trigger block found. Add an API Trigger block to this workflow.' - : executionKind === 'chat' - ? 'No chat trigger block found. Add a Chat Trigger block to this workflow.' - : 'No trigger block found for this workflow.' + const errorMsg = 'No start block found. Add a start block to this workflow.' logger.error(`[${requestId}] ${errorMsg}`) throw new Error(errorMsg) }