From ddde41bc1de6f7dea32b21a61ce2a5bf3bf8bba6 Mon Sep 17 00:00:00 2001 From: Guilhem Date: Thu, 1 Oct 2026 13:28:41 +0200 Subject: [PATCH] fix: block runs while a JSON input does not parse (#11463) * fix: block runs while a JSON input does not parse Co-Authored-By: Claude Opus 5.5 (1M context) * fix: clear json editor error on unmount and flush editors before run Co-Authored-By: Claude Opus 5.5 (1M context) * fix: restore validity when a nullable arg input is cleared Co-Authored-By: Claude Opus 5.5 (1M context) * fix: let field editors parse before the run check and reset the message on view switch Co-Authored-By: Claude Opus 5.5 (1M context) * fix: clear the run refusal message when form validity changes Co-Authored-By: Claude Opus 5.5 (1M context) --------- Co-authored-by: Claude Opus 5.5 (1M context) --- frontend/src/lib/components/ArgInput.svelte | 14 +++- frontend/src/lib/components/JsonEditor.svelte | 7 +- frontend/src/lib/components/JsonInputs.svelte | 73 ++++++++++++------- frontend/src/lib/components/RunForm.svelte | 31 +++++++- 4 files changed, 95 insertions(+), 30 deletions(-) diff --git a/frontend/src/lib/components/ArgInput.svelte b/frontend/src/lib/components/ArgInput.svelte index 49972d3b59..756b827105 100644 --- a/frontend/src/lib/components/ArgInput.svelte +++ b/frontend/src/lib/components/ArgInput.svelte @@ -253,6 +253,9 @@ let ignoreValueUndefined = $state(false) let error: string = $state('') + // Parse error of the JSON editor below, which already displays it. Text that does not parse + // never reaches `value`, so without this the field would stay valid on its last parsed value. + let jsonError: string = $state('') let isListJson = $state(false) let hasIsListJsonChanged = $state(false) @@ -417,9 +420,12 @@ '^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$' function validateInput(pattern: string | undefined, v: any, required: boolean): void { - if (nullable && emptyString(v)) { + if (jsonError) { error = '' - valid && (valid = true) + valid && (valid = false) + } else if (nullable && emptyString(v)) { + error = '' + !valid && (valid = true) } else if ( typeof v === 'string' && (v.startsWith('$var:') || v.startsWith('$res:') || v.startsWith('$jsonvar:')) @@ -563,6 +569,7 @@ $effect(() => { extra?.['nonEmpty'] + jsonError let args = [pattern, value, required] as const untrack(() => validateInput(...args)) }) @@ -1262,6 +1269,7 @@ dispatch('blur') }} code={rawValue} + bind:error={jsonError} on:changeValue={(e) => { setNewValueFromCode(e.detail) }} @@ -1284,6 +1292,7 @@ dispatch('blur') }} code={rawValue} + bind:error={jsonError} on:change={(e) => { value = e.detail }} @@ -1373,6 +1382,7 @@ dispatch('blur') }} code={rawValue} + bind:error={jsonError} on:changeValue={(e) => { setNewValueFromCode(e.detail) }} diff --git a/frontend/src/lib/components/JsonEditor.svelte b/frontend/src/lib/components/JsonEditor.svelte index f3d2d4eb2e..36c662733b 100644 --- a/frontend/src/lib/components/JsonEditor.svelte +++ b/frontend/src/lib/components/JsonEditor.svelte @@ -40,7 +40,12 @@ // Identity for this editor's entry in the unparseable registry, so a caller about to // persist what is on screen can refuse rather than save the last value that parsed. const unparseableKey = {} - onDestroy(() => setEditorUnparseable(unparseableKey, false)) + // Also clears a bound `error`: a parent gating validity on it would otherwise stay invalid + // after the editor that reported the error is gone. + onDestroy(() => { + error = '' + setEditorUnparseable(unparseableKey, false) + }) const dispatch = createEventDispatcher() const dispatchIfMounted = createDispatcherIfMounted(dispatch) diff --git a/frontend/src/lib/components/JsonInputs.svelte b/frontend/src/lib/components/JsonInputs.svelte index bb39c0aa77..baf2d142d2 100644 --- a/frontend/src/lib/components/JsonInputs.svelte +++ b/frontend/src/lib/components/JsonInputs.svelte @@ -1,6 +1,7 @@