feat(workflow): safer, clearer JSON inputs in the workflow builder#2601
Open
simlarsen wants to merge 1 commit into
Open
feat(workflow): safer, clearer JSON inputs in the workflow builder#2601simlarsen wants to merge 1 commit into
simlarsen wants to merge 1 commit into
Conversation
Configuring workflow components is hard, and the JSON-typed arguments are
the sharpest edge: request bodies, headers, DB queries and payloads all
rendered as a bare Monaco editor with no validation. A syntax slip (a
trailing comma, a missing quote) was only discovered when the workflow ran
and threw a cryptic "Invalid JSON provided for argument …" (see
App/FeatureSet/Workflow/Services/RunWorkflow.ts). Template tokens made it
worse — {{ variable }} references are not literal JSON, so the editor
offered no help distinguishing "not valid yet" from "actually broken".
This makes the JSON editing experience validate-as-you-type and blocks
saving broken config, while keeping the on-disk format byte-identical
(values are still stored as JSON strings and parsed at runtime, so existing
workflows are unaffected).
- New JSONArgumentInput: a token-aware JSON editor with live validation, a
clear inline "Invalid JSON" message, and a one-click Format button. It
understands {{ tokens }} (masking them before parsing), single-token
variable references, and {{#each}} template blocks, so variable usage no
longer reads as an error.
- Pure validation logic extracted to JSONArgumentInputUtils (React-free) and
covered by unit tests.
- ArgumentsForm now routes JSON / JSONArray / BaseModel / BaseModelArray /
Query / StringDictionary args (and Select without a tableName) through the
validating editor, and lifts each field's validity into the form so an
invalid JSON body disables Save.
- Honor the previously-unused Argument.isAdvanced flag: advanced fields
collapse behind a "Show advanced settings" toggle, so the common path is a
couple of fields. Auto-expands when an advanced field is required or
already set, so nothing important is hidden.
- Fix a validation-key collision: argument-form errors were reported under
the same "id" key as the identifier field and could clobber it; use
distinct "arguments" / "json:<argId>" keys.
- Replace the misused error-style empty state ("This step does not need any
settings") with a neutral note.
- Make the component value picker search case-insensitive.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Configuring workflow components is hard to get right, and the JSON-typed arguments are the sharpest edge. Request bodies, HTTP headers, DB queries and payloads all rendered as a bare Monaco editor with no validation. A syntax slip — a trailing comma, a missing quote — was only discovered when the workflow ran, throwing a cryptic
Invalid JSON provided for argument …(App/FeatureSet/Workflow/Services/RunWorkflow.ts:596-607). Template tokens made it worse:{{ variable }}references aren't literal JSON, so the editor couldn't tell "not valid yet" from "actually broken."This PR makes JSON editing validate-as-you-type and blocks saving broken config — while keeping the on-disk format byte-identical (values are still stored as JSON strings and parsed at runtime, so existing workflows are unaffected and the executor is untouched).
What changed
JSONArgumentInput— a token-aware JSON editor with:{{ tokens }}(masked before parsing), single-token variable references, and{{#each}}template blocks — so variable usage no longer reads as an error.JSONArgumentInputUtils— the pure validation logic, extracted React-free and covered by unit tests.ArgumentsForm:JSON/JSONArray/BaseModel/BaseModelArray/Query/StringDictionaryargs (andSelectwithout atableName) through the validating editor;Argument.isAdvancedflag — advanced fields collapse behind a "Show advanced settings" toggle so the common path is a couple of fields (auto-expands when an advanced field is required or already set, so nothing important is hidden);"id"key as the identifier field and could clobber it; now uses distinct"arguments"/"json:<argId>"keys;ComponentValuePickerModal— case-insensitive search.Safety / compatibility
RunWorkflow/API/UtilsstillJSON.parsethem at runtime. Verified the server reads these astypeof === "string"before parsing.Common/UI/Components/Workflow/*— the path the workflow builder actually renders (Dashboard/View/Builder.tsx→Common/UI/.../Workflow). The separateDashboard/Canvas/*copy (dashboard tiles) is untouched.Testing
tsc --noEmit✓ ·eslint✓{{#each}}blocks, stateless token detection — all passing.Context / follow-ups
This is Phase 0 of a larger workflow-builder simplification (validated via a multi-perspective design pass). Natural next steps, not in this PR: dock the config modal into a side inspector, turn
{{…}}strings into data chips with upstream-only autocomplete, node-face config summaries, structured editors (key/value rows for headers, a filter builder for queries), labeled ports, and a template-gallery cold start.🤖 Generated with Claude Code