From 172bfd7285e5d9d94a7d1a53bc430e2d0cf02868 Mon Sep 17 00:00:00 2001 From: Jakob Heuser Date: Tue, 20 Oct 2026 12:26:55 -0700 Subject: [PATCH] fix(check): retry removing an interrupted run's directory when a queued log write recreates a file --- .changeset/run-directory-signal-cleanup.md | 5 +++++ packages/cli/src/rules/run-directory.ts | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/run-directory-signal-cleanup.md diff --git a/.changeset/run-directory-signal-cleanup.md b/.changeset/run-directory-signal-cleanup.md new file mode 100644 index 00000000..4a273a6c --- /dev/null +++ b/.changeset/run-directory-signal-cleanup.md @@ -0,0 +1,5 @@ +--- +"@taskless/cli": patch +--- + +Interrupting `taskless check` with Ctrl-C or SIGTERM now reliably removes the run's `.taskless/.run/` directory. Before this fix, a log entry that was still being written could recreate its file mid-removal, and the directory was left behind until a later run swept it. diff --git a/packages/cli/src/rules/run-directory.ts b/packages/cli/src/rules/run-directory.ts index 4c864538..635f5540 100644 --- a/packages/cli/src/rules/run-directory.ts +++ b/packages/cli/src/rules/run-directory.ts @@ -363,8 +363,17 @@ export async function openRun( return; } if (!preserve) { + // A queued append may be mid-flight on a worker thread, and can + // recreate its log between the unlinks and the final rmdir, which + // then fails ENOTEMPTY. Retrying removes the late file; the worker + // finishes while this thread waits. Bounded at 150ms. try { - rmSync(path, { recursive: true, force: true }); + rmSync(path, { + recursive: true, + force: true, + maxRetries: 5, + retryDelay: 10, + }); } catch { // The next run's sweep removes it. }