@@ -33,7 +33,11 @@ import { createHttpResponseFromBlock, workflowHasResponseBlock } from '@/lib/wor
3333import { executeWorkflowJob , type WorkflowExecutionPayload } from '@/background/workflow-execution'
3434import { normalizeName } from '@/executor/constants'
3535import { ExecutionSnapshot } from '@/executor/execution/snapshot'
36- import type { ExecutionMetadata , IterationContext } from '@/executor/execution/types'
36+ import type {
37+ ExecutionMetadata ,
38+ IterationContext ,
39+ SerializableExecutionState ,
40+ } from '@/executor/execution/types'
3741import type { NormalizedBlockOutput , StreamingExecution } from '@/executor/types'
3842import { hasExecutionResult } from '@/executor/utils/errors'
3943import { Serializer } from '@/serializer'
@@ -276,24 +280,41 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
276280 } = validation . data
277281
278282 // Resolve runFromBlock snapshot from executionId if needed
279- let runFromBlock = rawRunFromBlock
280- if ( runFromBlock && ! runFromBlock . sourceSnapshot && runFromBlock . executionId ) {
281- const { getExecutionState, getLatestExecutionState } = await import (
282- '@/lib/workflows/executor/execution-state'
283- )
284- const snapshot =
285- runFromBlock . executionId === 'latest'
286- ? await getLatestExecutionState ( workflowId )
287- : await getExecutionState ( runFromBlock . executionId )
288- if ( ! snapshot ) {
283+ let resolvedRunFromBlock :
284+ | { startBlockId : string ; sourceSnapshot : SerializableExecutionState }
285+ | undefined
286+ if ( rawRunFromBlock ) {
287+ if ( rawRunFromBlock . sourceSnapshot ) {
288+ resolvedRunFromBlock = {
289+ startBlockId : rawRunFromBlock . startBlockId ,
290+ sourceSnapshot : rawRunFromBlock . sourceSnapshot as SerializableExecutionState ,
291+ }
292+ } else if ( rawRunFromBlock . executionId ) {
293+ const { getExecutionState, getLatestExecutionState } = await import (
294+ '@/lib/workflows/executor/execution-state'
295+ )
296+ const snapshot =
297+ rawRunFromBlock . executionId === 'latest'
298+ ? await getLatestExecutionState ( workflowId )
299+ : await getExecutionState ( rawRunFromBlock . executionId )
300+ if ( ! snapshot ) {
301+ return NextResponse . json (
302+ {
303+ error : `No execution state found for ${ rawRunFromBlock . executionId === 'latest' ? 'workflow' : `execution ${ rawRunFromBlock . executionId } ` } . Run the full workflow first.` ,
304+ } ,
305+ { status : 400 }
306+ )
307+ }
308+ resolvedRunFromBlock = {
309+ startBlockId : rawRunFromBlock . startBlockId ,
310+ sourceSnapshot : snapshot ,
311+ }
312+ } else {
289313 return NextResponse . json (
290- {
291- error : `No execution state found for ${ runFromBlock . executionId === 'latest' ? 'workflow' : `execution ${ runFromBlock . executionId } ` } . Run the full workflow first.` ,
292- } ,
314+ { error : 'runFromBlock requires either sourceSnapshot or executionId' } ,
293315 { status : 400 }
294316 )
295317 }
296- runFromBlock = { startBlockId : runFromBlock . startBlockId , sourceSnapshot : snapshot }
297318 }
298319
299320 // For API key and internal JWT auth, the entire body is the input (except for our control fields)
@@ -520,7 +541,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
520541 includeFileBase64,
521542 base64MaxBytes,
522543 stopAfterBlockId,
523- runFromBlock,
544+ runFromBlock : resolvedRunFromBlock ,
524545 abortSignal : timeoutController . signal ,
525546 } )
526547
@@ -861,7 +882,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
861882 includeFileBase64,
862883 base64MaxBytes,
863884 stopAfterBlockId,
864- runFromBlock,
885+ runFromBlock : resolvedRunFromBlock ,
865886 } )
866887
867888 if ( result . status === 'paused' ) {
0 commit comments