From 90756f92b0ae0ca50998765c8ee0f21f40c19ca2 Mon Sep 17 00:00:00 2001 From: Phil Larson Date: Mon, 29 Jun 2026 12:36:52 -0700 Subject: [PATCH 1/2] fix(core): await secrets store close during TaskStore shutdown --- .changeset/thin-rocks-post.md | 7 +++++++ packages/core/src/store.ts | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 .changeset/thin-rocks-post.md diff --git a/.changeset/thin-rocks-post.md b/.changeset/thin-rocks-post.md new file mode 100644 index 0000000000..7408a397ce --- /dev/null +++ b/.changeset/thin-rocks-post.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Wait for task store secret database handles to close before cleanup. +category: fix +dev: Awaits the async secrets store close path during TaskStore shutdown to avoid teardown races. diff --git a/packages/core/src/store.ts b/packages/core/src/store.ts index cc05a95a0c..e3814e957e 100644 --- a/packages/core/src/store.ts +++ b/packages/core/src/store.ts @@ -16135,8 +16135,17 @@ ${stepsSection}`; this._archiveDb = null; } if (this.secretsCentralCore) { - void this.secretsCentralCore.close(); + // Await the secrets central core close: CentralCore.close() is async, so a + // fire-and-forget call would let close() resolve while the secrets SQLite + // handle is still draining on a later microtask, racing temp-root cleanup + // under the loaded package test lane. Await it like the other handles above. + const secretsCentralCore = this.secretsCentralCore; this.secretsCentralCore = null; + try { + await secretsCentralCore.close(); + } catch (err) { + console.warn(`[fusion] Could not close secrets central core on TaskStore close:`, err); + } } this.secretsStore = null; if (this.pluginStore) { From af99a353f09e1998fb9875cba31c79e983a27435 Mon Sep 17 00:00:00 2001 From: Phil Larson Date: Mon, 29 Jun 2026 12:41:20 -0700 Subject: [PATCH 2/2] test(engine): align workflow gate expectations --- packages/core/src/store.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/core/src/store.ts b/packages/core/src/store.ts index e3814e957e..fcaec8b29d 100644 --- a/packages/core/src/store.ts +++ b/packages/core/src/store.ts @@ -16135,10 +16135,11 @@ ${stepsSection}`; this._archiveDb = null; } if (this.secretsCentralCore) { - // Await the secrets central core close: CentralCore.close() is async, so a - // fire-and-forget call would let close() resolve while the secrets SQLite - // handle is still draining on a later microtask, racing temp-root cleanup - // under the loaded package test lane. Await it like the other handles above. + /** + * FNXC:TaskStoreShutdown 2026-06-29-13:04: + * TaskStore.close() must deterministically await the cached secrets CentralCore close before temp-root cleanup and test teardown continue. + * CentralCore.close() is currently synchronous internally, but awaiting the async contract prevents unhandled rejections and preserves shutdown safety if the central secrets handle gains asynchronous cleanup. + */ const secretsCentralCore = this.secretsCentralCore; this.secretsCentralCore = null; try {