From d80608cdd5459992a3da6d2b761c18e7d8969e31 Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Tue, 27 Jan 2026 16:20:41 -0800 Subject: [PATCH] Fix --- .../hooks/use-workflow-execution.ts | 50 ++++++++++++++++++- apps/sim/executor/execution/executor.ts | 8 ++- 2 files changed, 55 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 ec37906fa..6f610ff9f 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 @@ -15,6 +15,7 @@ import { TriggerUtils, } from '@/lib/workflows/triggers/triggers' import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-current-workflow' +import { getBlock } from '@/blocks' import type { SerializableExecutionState } from '@/executor/execution/types' import type { BlockLog, BlockState, ExecutionResult, StreamingExecution } from '@/executor/types' import { hasExecutionResult } from '@/executor/utils/errors' @@ -1477,8 +1478,29 @@ export function useWorkflowExecution() { const candidates = resolveStartCandidates(mergedStates, { execution: 'manual' }) const candidate = candidates.find((c) => c.blockId === blockId) + logger.info('Run-from-block trigger analysis', { + blockId, + blockType: workflowBlocks[blockId]?.type, + blockTriggerMode: workflowBlocks[blockId]?.triggerMode, + candidateFound: !!candidate, + candidatePath: candidate?.path, + allCandidates: candidates.map((c) => ({ + blockId: c.blockId, + type: c.block.type, + path: c.path, + })), + }) + if (candidate) { - if (triggerNeedsMockPayload(candidate)) { + const needsMockPayload = triggerNeedsMockPayload(candidate) + logger.info('Trigger mock payload check', { + needsMockPayload, + path: candidate.path, + isExternalTrigger: candidate.path === StartBlockPath.EXTERNAL_TRIGGER, + blockType: candidate.block.type, + }) + + if (needsMockPayload) { workflowInput = extractTriggerMockPayload(candidate) logger.info('Extracted mock payload for trigger block', { blockId, workflowInput }) } else if ( @@ -1500,6 +1522,32 @@ export function useWorkflowExecution() { } } } + } else { + // Fallback for trigger blocks not found in candidates + // This can happen when the block is a trigger by position (no incoming edges) + // but wasn't classified as a start candidate (e.g., triggerMode not set) + const block = mergedStates[blockId] + if (block) { + const blockConfig = getBlock(block.type) + const hasTriggers = blockConfig?.triggers?.available?.length + + if (hasTriggers || block.triggerMode) { + // Block has trigger capability - extract mock payload + const syntheticCandidate = { + blockId, + block, + path: StartBlockPath.EXTERNAL_TRIGGER, + } + workflowInput = extractTriggerMockPayload(syntheticCandidate) + logger.info('Extracted mock payload for trigger block (fallback)', { + blockId, + blockType: block.type, + hasTriggers, + triggerMode: block.triggerMode, + workflowInput, + }) + } + } } } diff --git a/apps/sim/executor/execution/executor.ts b/apps/sim/executor/execution/executor.ts index ec5fde24f..ce3562969 100644 --- a/apps/sim/executor/execution/executor.ts +++ b/apps/sim/executor/execution/executor.ts @@ -107,7 +107,8 @@ export class DAGExecutor { startBlockId: string, sourceSnapshot: SerializableExecutionState ): Promise { - const dag = this.dagBuilder.build(this.workflow) + // Pass startBlockId as trigger so DAG includes it and all downstream blocks + const dag = this.dagBuilder.build(this.workflow, startBlockId) const executedBlocks = new Set(sourceSnapshot.executedBlocks) const validation = validateRunFromBlock(startBlockId, dag, executedBlocks) @@ -297,7 +298,10 @@ export class DAGExecutor { skipStarterBlockInit: true, }) } else if (overrides?.runFromBlockContext) { - logger.info('Run-from-block mode: skipping starter block initialization', { + // In run-from-block mode, still initialize the start block with workflow input + // This ensures trigger blocks get their mock payload + this.initializeStarterBlock(context, state, overrides.runFromBlockContext.startBlockId) + logger.info('Run-from-block mode: initialized start block', { startBlockId: overrides.runFromBlockContext.startBlockId, }) } else {