Skip to content

fix(workflows): validate YAML on import so misplaced keys aren't silently dropped (#6274) - #6647

Open
DPS0340 wants to merge 1 commit into
keephq:mainfrom
DPS0340:fix/validate-workflow-yaml-on-import
Open

fix(workflows): validate YAML on import so misplaced keys aren't silently dropped (#6274)#6647
DPS0340 wants to merge 1 commit into
keephq:mainfrom
DPS0340:fix/validate-workflow-yaml-on-import

Conversation

@DPS0340

@DPS0340 DPS0340 commented Jul 25, 2026

Copy link
Copy Markdown

Fixes #6274.

What was wrong

Importing a workflow YAML where with: is a sibling of provider: instead of nested inside it saved successfully and then ran with zero parameters — no warning, no validation error. Users hit it as HttpProvider._notify() missing 2 required positional arguments or Message is required at runtime, with nothing pointing at the YAML.

The import handler in workflow-builder-widget.tsx called parseWorkflowYamlStringToJSON, which is a bare yaml.parse() — its own comment says // todo: use zod schema to parse and have type safety. Nothing validated the shape.

Meanwhile every consumer reads provider.with:

  • _parse_steps_step.get("provider", {}).get("with") (keep/parser/parser.py)
  • _parse_actionsprovider.get("with", {}) (same file)
  • frontend getV2StepOrV2ActionactionOrStep.provider?.with

So a step-level with: is unreachable everywhere. I verified this directly rather than assuming — parsing the reported YAML gives:

provider.with  → undefined          ← what the backend and UI read
step-level with → { message: "test" }  ← where the parameters actually sit

The fix

Use the validating parser that already exists in the codebase. parseWorkflowYamlToJSON applies YamlWorkflowDefinitionSchema, whose step schema is .strict(), so an unrecognised key at step level is rejected:

const result = parseWorkflowYamlToJSON(contents);
if (!result.success) {
  throw new Error(fromZodError(result.error).toString());
}

The existing catch already routes to showErrorToast, so the user now gets an actionable message at import time instead of a broken workflow.

No new helper and no new convention: parseWorkflowYamlToJSON and fromZodError are both already used together in keep-ui/scripts/validate-workflow-examples.ts, and zod-validation-error is already a dependency.

Scope

Only the import path in BuilderWorkflowYAMLImport. I deliberately did not touch the backend parser or add a migration — those are worth doing but are separate changes with wider blast radius, and this is the one that stops the silent data loss at the point of entry.

I also left parseWorkflowYamlStringToJSON in place; it has other callers, and changing it would affect paths I haven't verified.

Tests

keep-ui/widgets/workflow-builder/__tests__/workflow-import-validation.test.ts — pins the import handler's validation:

case expected
with: sibling of provider: rejected, and the message names with
same workflow, with: nested accepted
the misplaced form provider.with is undefined while the params sit at step level — shows why accepting it is harmful

Plus two cases in the existing parseWorkflowYamlToJSON.test.ts covering the schema itself.

The second row of each pair is a guard rail: a change that simply rejected more would break them.

Worth noting — that guard rail already earned its place. My first version of the "accepts nested" fixture failed because it was missing a required description, not because of the misplacement. Without the positive case I'd have shipped a test that proved nothing.

Verification

npx jest widgets/workflow-builder entities/workflows: 161 passed / 18 suites, up from 158 before. npx tsc --noEmit reports no errors in the touched files.

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jul 25, 2026
@CLAassistant

CLAassistant commented Jul 25, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 Bug]: Workflow UI editor silently moves with: out of provider:, breaking every action

2 participants