From d9dcaaf0c6dbfed6906b00bbd92712e054978609 Mon Sep 17 00:00:00 2001 From: Vaggeilis Yfantis Date: Sun, 15 Feb 2026 02:00:15 +0200 Subject: [PATCH 1/2] feat: Cancel workflow via the client with workflow id --- packages/openworkflow/client.test.ts | 27 +++++++++++++++++++++++++++ packages/openworkflow/client.ts | 14 ++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/packages/openworkflow/client.test.ts b/packages/openworkflow/client.test.ts index 0e154cb8..cb5e50db 100644 --- a/packages/openworkflow/client.test.ts +++ b/packages/openworkflow/client.test.ts @@ -412,6 +412,33 @@ describe("OpenWorkflow", () => { expect(workflowRun?.finishedAt).not.toBeNull(); }); + test("cancels workflow run via client by ID", async () => { + const backend = await createBackend(); + const client = new OpenWorkflow({ backend }); + + const workflow = client.defineWorkflow({ name: "cancel-test" }, noopFn); + const handle = await workflow.run({ value: 1 }); + + await client.cancelWorkflowRun(handle.workflowRun.id); + + const workflowRun = await backend.getWorkflowRun({ + workflowRunId: handle.workflowRun.id, + }); + expect(workflowRun?.status).toBe("canceled"); + expect(workflowRun?.finishedAt).not.toBeNull(); + }); + + test("throws when canceling a non-existent workflow run", async () => { + const backend = await createBackend(); + const client = new OpenWorkflow({ backend }); + + const nonExistentId = randomUUID(); + + await expect( + client.cancelWorkflowRun(nonExistentId), + ).rejects.toThrow(`Workflow run ${nonExistentId} does not exist`); + }); + describe("defineWorkflowSpec / implementWorkflow API", () => { test("defineWorkflowSpec returns a spec that can be used to schedule runs", async () => { const backend = await createBackend(); diff --git a/packages/openworkflow/client.ts b/packages/openworkflow/client.ts index 6be212b1..ebdd89e1 100644 --- a/packages/openworkflow/client.ts +++ b/packages/openworkflow/client.ts @@ -157,6 +157,20 @@ export class OpenWorkflow { return new RunnableWorkflow(this, workflow); } + + /** + * Cancels the workflow run with the given ID. Only workflow runs in pending, running, or sleeping + * status can be canceled. + * @param workflowRunId - The ID of the workflow run to cancel + * @returns Promise + * @example + * ```ts + * await ow.cancelWorkflowRun("123"); + * ``` + */ + async cancelWorkflowRun(workflowRunId: string): Promise { + await this.backend.cancelWorkflowRun({ workflowRunId }); + } } /** From eec63c3ffe6697215578527f0341d1f94f0b0e49 Mon Sep 17 00:00:00 2001 From: Vaggeilis Yfantis Date: Sun, 15 Feb 2026 16:57:50 +0200 Subject: [PATCH 2/2] chore: Fix CI issues --- packages/openworkflow/client.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/openworkflow/client.test.ts b/packages/openworkflow/client.test.ts index cb5e50db..533aeab7 100644 --- a/packages/openworkflow/client.test.ts +++ b/packages/openworkflow/client.test.ts @@ -434,9 +434,9 @@ describe("OpenWorkflow", () => { const nonExistentId = randomUUID(); - await expect( - client.cancelWorkflowRun(nonExistentId), - ).rejects.toThrow(`Workflow run ${nonExistentId} does not exist`); + await expect(client.cancelWorkflowRun(nonExistentId)).rejects.toThrow( + `Workflow run ${nonExistentId} does not exist`, + ); }); describe("defineWorkflowSpec / implementWorkflow API", () => {