From 6664ce6dc0c5fbc283303148de06d6bb85e4acf7 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Thu, 25 Jun 2026 17:34:54 +0200 Subject: [PATCH] fix(frontend): apply script editor timeout to preview/Test runs (#9794) The custom timeout configured in the script editor settings was only honored for deployed script runs: it is persisted on the script row and passed as custom_timeout when running by hash/path. Preview ("Test") runs derive their timeout solely from the `timeout` query param of /jobs/run/preview, which the editor never sent, so Test silently fell back to the instance default. Forward the editor's timeout setting through ScriptBuilder -> ScriptEditor -> JobLoader.runPreview as the preview run's timeout query param. The backend already clamps custom_timeout against the instance max in resolve_job_timeout, so previews get the same ceiling as deployed runs. Co-authored-by: Claude Opus 4.8 (1M context) --- backend/windmill-api/openapi.yaml | 5 +++++ frontend/src/lib/components/JobLoader.svelte | 4 +++- frontend/src/lib/components/ScriptBuilder.svelte | 1 + frontend/src/lib/components/ScriptEditor.svelte | 9 ++++++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index fe8ae098af..71b00e30dd 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -11800,6 +11800,11 @@ paths: in: query schema: type: boolean + - name: timeout + description: custom timeout in seconds for this preview run + in: query + schema: + type: integer - $ref: "#/components/parameters/NewJobId" requestBody: diff --git a/frontend/src/lib/components/JobLoader.svelte b/frontend/src/lib/components/JobLoader.svelte index b0d7dae0e0..a32eecf93a 100644 --- a/frontend/src/lib/components/JobLoader.svelte +++ b/frontend/src/lib/components/JobLoader.svelte @@ -336,12 +336,14 @@ callbacks?: Callbacks, flowPath?: string, modules?: Record | null, - tempScriptRefs?: Record + tempScriptRefs?: Record, + timeout?: number ): Promise { return abstractRun( () => JobService.runScriptPreview({ workspace: $workspaceStore!, + timeout, requestBody: { path, content: code, diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index 7599bae9e5..ec7460b3ae 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -2016,6 +2016,7 @@ stablePathForCaptures={initialPath || fakeInitialPath} bind:code={script.content} lang={script.language} + timeout={script.timeout} kind={script.kind} autoKind={script.auto_kind} {template} diff --git a/frontend/src/lib/components/ScriptEditor.svelte b/frontend/src/lib/components/ScriptEditor.svelte index 4ba8c9f295..54be27f787 100644 --- a/frontend/src/lib/components/ScriptEditor.svelte +++ b/frontend/src/lib/components/ScriptEditor.svelte @@ -158,6 +158,10 @@ // succeeded. requireValidAssets?: boolean args: Record + // Custom timeout (in seconds) from the script settings. Forwarded to the + // preview run so "Test" honors the same timeout a deployed run would, + // instead of silently falling back to the instance default. + timeout?: number selectedTab?: 'main' | 'preprocessor' | 'diagram' hasPreprocessor?: boolean captureTable?: CaptureTable | undefined @@ -215,6 +219,7 @@ customUi = undefined, requireValidAssets = false, args = $bindable(), + timeout = undefined, selectedTab = $bindable('main'), hasPreprocessor = $bindable(false), captureTable = $bindable(undefined), @@ -791,7 +796,9 @@ } }, undefined, - activeModuleTab !== null ? undefined : modules + activeModuleTab !== null ? undefined : modules, + undefined, + timeout ) if (job) { onTestJob?.({ jobId: job })