A workflow refused by validation is never partially stored
The rule
- A workflow that fails validation on create or on update is refused with 422 carrying
success: false, a human-readableerror, anddetails, a list of{code, message, locator}entries, one per error, eachlocatornaming the position in the submitted workflow the error is about. - Only errors refuse and only errors are reported: a workflow carrying warnings alone is stored, and its warnings appear nowhere in the response.
- Create and update refuse identically, and a refused update leaves the stored workflow untouched.
What it means
A workflow either passes validation or it is refused whole; there is no
version of "stored, but with problems noted". That symmetry runs both ways.
On the refusing side, every error is reported — none is dropped for being
one of several — and each carries a locator naming where in the submitted
workflow it applies, since a client acting on the refusal needs to point at
the offending part without guessing from the message alone. On the
accepting side, a warning is not a smaller version of an error: it never
blocks the save and it never appears in the response, so a caller cannot
detect from the write alone that anything was noted.
Create and update are refused by exactly the same check, and a refused update leaves the stored workflow exactly as it was — the same guarantee STORE-3 gives a refused create.
Example
Two requests to the same door, one over the line and one short of it.
POST /api/flowdrop/workflows
{"id": "ghost_wf", "name": "Ghost WF", "nodes": [ … ]}POST /api/flowdrop/workflows
{"id": "warn_wf", "name": "Warn WF", "nodes": [ … ]}The first comes back as {"success": false, "error": "Workflow validation failed", "details": [{"code": "R1_PLUGIN_MISSING", "message": "…", "locator": "…"}]} —
one entry per error, the whole shape a client can rely on regardless of which
check fired (R1.a). Nothing from the request was stored. The second is
accepted outright: an unrecognised config key is a warning, not an error, so
it neither blocks the save nor shows up anywhere in the response.