Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 19 additions & 1 deletion apps/sim/executor/handlers/condition/condition-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ describe('ConditionBlockHandler', () => {
timeout: 5000,
envVars: mockContext.environmentVariables,
workflowVariables: mockContext.workflowVariables,
blockData: { 'source-block-1': { value: 10, text: 'hello' } },
blockData: {},
blockNameMapping: { sourceblock: 'source-block-1' },
_context: {
workflowId: 'test-workflow-id',
Expand All @@ -190,6 +190,24 @@ describe('ConditionBlockHandler', () => {
)
})

it('should never forward collected block outputs in the request body', async () => {
mockCollectBlockData.mockReturnValueOnce({
blockData: { 'huge-block': { payload: 'x'.repeat(1024) } },
blockNameMapping: { hugeblock: 'huge-block' },
})
mockExecuteTool.mockResolvedValueOnce({ success: true, output: { result: true } })

const conditions = [
{ id: 'cond1', title: 'if', value: 'true' },
{ id: 'else1', title: 'else', value: '' },
]

await handler.execute(mockContext, mockBlock, { conditions: JSON.stringify(conditions) })

const [, toolParams] = mockExecuteTool.mock.calls[0]
expect(toolParams.blockData).toEqual({})
})

it('should select the else path if other conditions fail', async () => {
mockExecuteTool.mockResolvedValueOnce({ success: true, output: { result: false } })

Expand Down
10 changes: 8 additions & 2 deletions apps/sim/executor/handlers/condition/condition-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const CONDITION_TIMEOUT_MS = 5000
* Evaluates a single condition expression.
* The resolver preserves legacy Condition expression substitution before this function executes the
* resulting JavaScript through the shared function execution boundary.
*
* `blockData` is deliberately empty: the resolver already inlines every `<block.field>` reference
* into the expression before this runs, so shipping the run's accumulated block outputs would only
* inflate the request body. Sending them blew the 10MB body cap on wide subflows, where a single
* flat `blockStates` map holds every branch's outputs.
*
* Returns true if condition is met, false otherwise.
*/
async function evaluateConditionExpression(
Expand All @@ -36,7 +42,7 @@ async function evaluateConditionExpression(
const contextSetup = `const context = ${JSON.stringify(evalContext)};`
const code = `${contextSetup}\nreturn Boolean(${conditionExpression})`

const { blockData, blockNameMapping, blockOutputSchemas } = collectBlockData(ctx, currentNodeId)
const { blockNameMapping, blockOutputSchemas } = collectBlockData(ctx, currentNodeId)

const result = await executeTool(
'function_execute',
Expand All @@ -45,7 +51,7 @@ async function evaluateConditionExpression(
timeout: CONDITION_TIMEOUT_MS,
envVars: normalizeStringRecord(ctx.environmentVariables),
workflowVariables: normalizeWorkflowVariables(ctx.workflowVariables),
blockData,
blockData: {},
blockNameMapping,
blockOutputSchemas,
_context: {
Expand Down
Loading