From 28fbd0c0861420b33a55397c454aeb3b4959981b Mon Sep 17 00:00:00 2001 From: Siddharth Ganesan Date: Tue, 27 Jan 2026 18:25:12 -0800 Subject: [PATCH] Fix --- .../sim/executor/utils/run-from-block.test.ts | 10 +++++----- apps/sim/executor/utils/run-from-block.ts | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/apps/sim/executor/utils/run-from-block.test.ts b/apps/sim/executor/utils/run-from-block.test.ts index 528b44def..082f7f54f 100644 --- a/apps/sim/executor/utils/run-from-block.test.ts +++ b/apps/sim/executor/utils/run-from-block.test.ts @@ -331,9 +331,10 @@ describe('validateRunFromBlock', () => { expect(result.error).toContain('Upstream dependency not executed') }) - it('rejects blocks with unexecuted transitive upstream dependencies', () => { + it('allows running from block when immediate predecessor was executed (ignores transitive)', () => { // A → X → B → C, where X is new (not executed) - // Running from C should fail because X in upstream chain wasn't executed + // Running from C is allowed because B (immediate predecessor) was executed + // C will use B's cached output - doesn't matter that X is new const dag = createDAG([ createNode('A', [{ target: 'X' }]), createNode('X', [{ target: 'B' }]), @@ -344,9 +345,8 @@ describe('validateRunFromBlock', () => { const result = validateRunFromBlock('C', dag, executedBlocks) - expect(result.valid).toBe(false) - expect(result.error).toContain('Upstream dependency not executed') - expect(result.error).toContain('X') + // Valid because C's immediate predecessor B was executed + expect(result.valid).toBe(true) }) it('allows blocks with no dependencies even if not previously executed', () => { diff --git a/apps/sim/executor/utils/run-from-block.ts b/apps/sim/executor/utils/run-from-block.ts index dbe2e3fcd..0f4bf62b8 100644 --- a/apps/sim/executor/utils/run-from-block.ts +++ b/apps/sim/executor/utils/run-from-block.ts @@ -169,15 +169,18 @@ export function validateRunFromBlock( if (node.metadata.isSentinel) { return { valid: false, error: 'Cannot run from sentinel node' } } - } - // Check that ALL upstream blocks were executed (transitive check) - const { upstreamSet } = computeExecutionSets(dag, blockId) - for (const upstreamId of upstreamSet) { - if (!executedBlocks.has(upstreamId)) { - return { - valid: false, - error: `Upstream dependency not executed: ${upstreamId}`, + // Check immediate upstream dependencies were executed + for (const sourceId of node.incomingEdges) { + const sourceNode = dag.nodes.get(sourceId) + // Skip sentinel nodes - they're internal and not in executedBlocks + if (sourceNode?.metadata.isSentinel) continue + + if (!executedBlocks.has(sourceId)) { + return { + valid: false, + error: `Upstream dependency not executed: ${sourceId}`, + } } } }