Skip to content

Commit 5c446f1

Browse files
authored
fix(function): omit oversized display code instead of failing the execution (#8357)
1 parent 2aed9b5 commit 5c446f1

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

‎apps/sim/tools/function/execute.test.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
MOUNTED_WORKSPACE_FILES_PROVENANCE_KEY,
66
PRIVATE_SECRET_PROVENANCE_FIELD,
77
} from '@/lib/execution/private-tool-metadata'
8+
import { MAX_FUNCTION_CODE_LENGTH } from '@/lib/function-execution/limits'
89
import { buildFunctionExecuteBody, functionExecuteTool } from '@/tools/function/execute'
910
import { createLLMToolSchema, createUserToolSchema } from '@/tools/params'
1011

@@ -59,6 +60,24 @@ describe('Function Execute Tool', () => {
5960
expect(body.timeout).toBe(DEFAULT_EXECUTION_TIMEOUT_MS)
6061
})
6162

63+
it('sends display code the route accepts when inlined references outgrow the source cap', () => {
64+
const inlinedValue = 'x'.repeat(MAX_FUNCTION_CODE_LENGTH)
65+
const body = buildFunctionExecuteBody({
66+
code: 'return __blockRef_0.length',
67+
sourceCode: `return "${inlinedValue}".length`,
68+
contextVariables: { __blockRef_0: inlinedValue },
69+
})
70+
71+
expect(functionExecuteBodySchema.safeParse(body).success).toBe(true)
72+
expect(body.sourceCode).toBeUndefined()
73+
74+
const withinCap = buildFunctionExecuteBody({
75+
code: 'return __blockRef_0',
76+
sourceCode: 'return <api.data>',
77+
})
78+
expect(withinCap.sourceCode).toBe('return <api.data>')
79+
})
80+
6281
it('preserves reference context and large-value authorization', () => {
6382
const body = buildFunctionExecuteBody({
6483
code: 'return contextVariables.previous.result',

‎apps/sim/tools/function/execute.ts‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants'
1010
import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages'
1111
import { PRIVATE_SECRET_PROVENANCE_FIELD } from '@/lib/execution/private-tool-metadata'
1212
import { SANDBOX_INPUT_DIR, SANDBOX_OUTPUT_DIR } from '@/lib/execution/remote-sandbox/sandbox-paths'
13+
import { MAX_FUNCTION_CODE_LENGTH } from '@/lib/function-execution/limits'
1314
import type { UserFile } from '@/executor/types'
1415
import type { CodeExecutionInput, CodeExecutionOutput } from '@/tools/function/types'
1516
import type { InternalToolConfig } from '@/tools/types'
@@ -43,15 +44,24 @@ function normalizeSandboxInputFiles(value: unknown): FunctionExecuteBody['files'
4344
return userFiles.map((file) => ({ ...file }))
4445
}
4546

46-
/** Builds the canonical Function protocol body for both HTTP compatibility and in-process calls. */
47+
/**
48+
* Builds the canonical Function protocol body for both HTTP compatibility and in-process calls.
49+
*
50+
* `sourceCode` is the display copy used only to render errors, with referenced values inlined,
51+
* so it can far outgrow the executed code. Past the route's source cap it is omitted, and errors
52+
* fall back to the executed code, rather than failing a request whose executed code is in bounds.
53+
*/
4754
export function buildFunctionExecuteBody(params: CodeExecutionInput): FunctionExecuteBody {
4855
const codeContent = Array.isArray(params.code)
4956
? params.code.map((entry: { content: string }) => entry.content).join('\n')
5057
: params.code
5158

5259
return {
5360
code: codeContent,
54-
sourceCode: params.sourceCode,
61+
sourceCode:
62+
params.sourceCode !== undefined && params.sourceCode.length <= MAX_FUNCTION_CODE_LENGTH
63+
? params.sourceCode
64+
: undefined,
5565
language: params.language || DEFAULT_CODE_LANGUAGE,
5666
timeout: params.timeout || DEFAULT_EXECUTION_TIMEOUT_MS,
5767
title: params.title,

0 commit comments

Comments
 (0)