From dd11bdd0036e67c49faa93cab1a700da60e6956b Mon Sep 17 00:00:00 2001 From: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Date: Tue, 24 Mar 2026 09:14:06 -0500 Subject: [PATCH] fix: clean up attachments for killed subagent runs --- src/agents/subagent-registry.test.ts | 33 ++++++++++++++++++++++++++++ src/agents/subagent-registry.ts | 4 ++++ 2 files changed, 37 insertions(+) diff --git a/src/agents/subagent-registry.test.ts b/src/agents/subagent-registry.test.ts index 015fce8f296..16e9ee7d88b 100644 --- a/src/agents/subagent-registry.test.ts +++ b/src/agents/subagent-registry.test.ts @@ -1,3 +1,6 @@ +import { promises as fs } from "node:fs"; +import os from "node:os"; +import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const noop = () => {}; @@ -431,4 +434,34 @@ describe("subagent registry seam flow", () => { }); }); }); + + it("removes attachments for killed delete-mode runs", async () => { + const attachmentsRootDir = await fs.mkdtemp( + path.join(os.tmpdir(), "openclaw-kill-attachments-"), + ); + const attachmentsDir = path.join(attachmentsRootDir, "child"); + await fs.mkdir(attachmentsDir, { recursive: true }); + await fs.writeFile(path.join(attachmentsDir, "artifact.txt"), "artifact"); + + mod.registerSubagentRun({ + runId: "run-killed-delete-attachments", + childSessionKey: "agent:main:subagent:killed-delete-attachments", + requesterSessionKey: "agent:main:main", + requesterDisplayKey: "main", + task: "kill and delete attachments", + cleanup: "delete", + attachmentsDir, + attachmentsRootDir, + }); + + const updated = mod.markSubagentRunTerminated({ + runId: "run-killed-delete-attachments", + reason: "manual kill", + }); + + expect(updated).toBe(1); + await vi.waitFor(async () => { + await expect(fs.access(attachmentsDir)).rejects.toMatchObject({ code: "ENOENT" }); + }); + }); }); diff --git a/src/agents/subagent-registry.ts b/src/agents/subagent-registry.ts index f28fbe75f3c..ad6ed9b2e7f 100644 --- a/src/agents/subagent-registry.ts +++ b/src/agents/subagent-registry.ts @@ -1654,6 +1654,10 @@ export function markSubagentRunTerminated(params: { childSessionKey: entry.childSessionKey, }); }); + const shouldDeleteAttachments = entry.cleanup === "delete" || !entry.retainAttachmentsOnKeep; + if (shouldDeleteAttachments) { + void safeRemoveAttachmentsDir(entry); + } completeCleanupBookkeeping({ runId: entry.runId, entry,