Skip to content

fix(serve): triggers run the published version, not the draft (1.5.1) - #51

Merged
pallaoro merged 1 commit into
mainfrom
fix/serve-published-version
Aug 3, 2026
Merged

fix(serve): triggers run the published version, not the draft (1.5.1)#51
pallaoro merged 1 commit into
mainfrom
fix/serve-published-version

Conversation

@pallaoro

@pallaoro pallaoro commented Aug 3, 2026

Copy link
Copy Markdown
Member

Problem

POST /flows/:name/run on the flow server loaded the draft file directly:

const file = path.join(flowsDir, `${safe}.json`);   // workspace/flows/<name>.json

No version lookup. So every off-box caller ignored published versions:

  • external webhook fan-out (clawnify API webhooks.ts)
  • HTTP triggers (trg_ tokens)
  • dashboard / API "run flow"

Only the in-gateway flow_run tool honored .clawflow/versions/. Net effect: flow_publish was a no-op for the paths customers actually trigger, and editing a draft silently changed production — the inverse of what the CLI and docs promise ("drafts aren't live until you publish").

Fix

loadFlow resolves exactly like flow_run: latest published version first, draft only when nothing is published. The fallback keeps unpublished flows working, so no existing trigger breaks.

  • startFlowServer takes workspace explicitly (defaults to $OPENCLAW_WORKSPACE → cwd, same as before); the plugin passes the same workspace its flow_* tools use, so the two can't drift.
  • The run log line now records which definition ran (v3 vs draft (no published versions)).
  • skills/clawflow/SKILL.md states the trigger-side rule.

Test

tests/manage.test.ts — publish v1, corrupt the draft to invalid JSON, POST /run. A 202 proves the draft was never read; a 404 (old behavior) proves it was. Plus a fallback case and the existing no-flow 404.

Confirmed non-vacuous: the new test fails against the old loadFlow and passes with the fix. Full suite 173/173, tsc --noEmit clean.

The flow server's /flows/:name/run loaded the draft file directly, so every
off-box caller — external webhooks, HTTP triggers, dashboard runs — executed
whatever was last written to workspace/flows/<name>.json and ignored published
versions entirely. Only the in-gateway flow_run tool honored them.

That made "publish" meaningless for the paths customers actually trigger, and
inverted the safety story the surface promises: saving a draft silently
changed production while the CLI/docs said drafts aren't live.

loadFlow now resolves like flow_run does — latest published version first,
draft only when nothing has been published (so an unpublished flow still runs
the moment it's written, and no existing trigger breaks). The resolved source
is logged with the run line. startFlowServer takes the workspace explicitly;
the plugin passes the same one its flow_* tools use.

Test: publish v1, corrupt the draft, POST /run — 202 proves the draft was
never read. Verified it fails against the old loadFlow.
@pallaoro
pallaoro merged commit 70b4fba into main Aug 3, 2026
1 check passed
@pallaoro
pallaoro deleted the fix/serve-published-version branch August 3, 2026 21:40
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.

1 participant