Skip to content

feat(workflow): safer, clearer JSON inputs in the workflow builder#2601

Open
simlarsen wants to merge 1 commit into
masterfrom
feat/workflow-json-input-safety
Open

feat(workflow): safer, clearer JSON inputs in the workflow builder#2601
simlarsen wants to merge 1 commit into
masterfrom
feat/workflow-json-input-safety

Conversation

@simlarsen

Copy link
Copy Markdown
Contributor

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:
    • live validation + a clear inline "Invalid JSON" message (catches the trailing-comma / missing-quote footguns before the run),
    • a one-click Format button,
    • awareness of {{ 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:
    • routes JSON / JSONArray / BaseModel / BaseModelArray / Query / StringDictionary args (and Select without a tableName) through the validating editor;
    • lifts each field's validity into the form so an invalid JSON body disables Save;
    • honors 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);
    • fixes a validation-key collision — argument errors were reported under the same "id" key as the identifier field and could clobber it; now uses distinct "arguments" / "json:<argId>" keys;
    • replaces the misused error-style empty state ("This step does not need any settings") with a neutral note.
  • ComponentValuePickerModal — case-insensitive search.

Safety / compatibility

  • No storage or executor change. JSON args remain strings; RunWorkflow / API/Utils still JSON.parse them at runtime. Verified the server reads these as typeof === "string" before parsing.
  • Lands entirely in Common/UI/Components/Workflow/* — the path the workflow builder actually renders (Dashboard/View/Builder.tsxCommon/UI/.../Workflow). The separate Dashboard/Canvas/* copy (dashboard tiles) is untouched.

Testing

  • tsc --noEmit ✓ · eslint
  • New unit tests (9) for the validator: valid/invalid JSON, quoted & unquoted tokens, single-token variables, {{#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

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>
@simlarsen

Copy link
Copy Markdown
Contributor Author

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants