From 20d80ee133620fd6c000f4a9921bb7cc64bad69f Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Tue, 19 May 2026 14:44:50 +0100 Subject: [PATCH 1/3] add workaround --- packages/ws-worker/src/events/step-complete.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/ws-worker/src/events/step-complete.ts b/packages/ws-worker/src/events/step-complete.ts index 88eaa15da..8218faebe 100644 --- a/packages/ws-worker/src/events/step-complete.ts +++ b/packages/ws-worker/src/events/step-complete.ts @@ -22,6 +22,20 @@ export default async function onStepComplete( const step_id = state.activeStep as string; const job_id = state.activeJob as string; + if (!step_id) { + // Runs are lost in production now because sometimes the step-complete + // event gets triggered twice. In this case, the second one does not + // have an activeStep on the state object, so will send with + // step_id null. And lightning will complain (rightly!) and refuse + // to listen to subsequent events on the run (wrongly!) + // This is hard to diagnose in the wild so as a temporary measure, + // we're going to abort with a strong warning + context.logger?.warn( + `DUPLICATE_EVENT_ERROR: Run ${context.id} received two step:complete events for the same step. The second event has been suppressed to prevent a lost run.` + ); + return; + } + if (!state.dataclips) { state.dataclips = {}; } From a5968262f3b3eb6a2d9a97ade7499ebf37e8f87d Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Tue, 19 May 2026 14:48:00 +0100 Subject: [PATCH 2/3] versions --- packages/ws-worker/CHANGELOG.md | 6 ++++++ packages/ws-worker/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/ws-worker/CHANGELOG.md b/packages/ws-worker/CHANGELOG.md index 74ec4d793..05edb9068 100644 --- a/packages/ws-worker/CHANGELOG.md +++ b/packages/ws-worker/CHANGELOG.md @@ -1,5 +1,11 @@ # ws-worker +## 1.25.1 + +### Patch Changes + +- Add workaround for rare event duplication + ## 1.25.0 ### Minor Changes diff --git a/packages/ws-worker/package.json b/packages/ws-worker/package.json index 8d47201c2..25e8aa448 100644 --- a/packages/ws-worker/package.json +++ b/packages/ws-worker/package.json @@ -1,6 +1,6 @@ { "name": "@openfn/ws-worker", - "version": "1.25.0", + "version": "1.25.1", "description": "A Websocket Worker to connect Lightning to a Runtime Engine", "main": "dist/index.js", "type": "module", From aaea777e5234bf7da1f943e840d7aa5f3040051f Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Tue, 19 May 2026 15:02:30 +0100 Subject: [PATCH 3/3] update test --- packages/ws-worker/test/api/execute.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ws-worker/test/api/execute.test.ts b/packages/ws-worker/test/api/execute.test.ts index 404a003ab..8d0e70686 100644 --- a/packages/ws-worker/test/api/execute.test.ts +++ b/packages/ws-worker/test/api/execute.test.ts @@ -206,6 +206,7 @@ test('jobError should trigger step:complete with a reason and default state', as let stepCompleteEvent: any; const state = createRunState({ id: 'run-23' } as ExecutionPlan); + state.activeStep = 'a'; const channel = mockChannel({ [STEP_COMPLETE]: (evt) => {