← Back to PRs

#17488: fix(agents): skip workspace deletion when shared with other agents

by soumikbhatta open 2026-02-15 20:14 View on GitHub →
gateway commands agents stale size: S
## Summary - Problem: `agents delete` unconditionally trashes the resolved workspace directory. When multiple agents share the same workspace path (e.g. `~/Projects`), deleting one agent nukes the entire directory — destroying files belonging to other agents and the user's own projects. - Why it matters: Critical data loss. Real-world incident: deleting a secondary agent trashed a user's entire `~/Projects` directory containing all repos, configs, and workspace files. - What changed: Added `isWorkspaceSharedByOtherAgent()` helper that checks all registered agents + the implicit default agent before deletion. Both the CLI (`agents.commands.delete.ts`) and gateway handler (`agents.ts`) now skip workspace trashing when the path is shared. - What did NOT change (scope boundary): `moveToTrash` itself, agent config pruning, `--force` flag behavior, session/agentDir deletion (those are per-agent and always safe to delete). lobster-biscuit ## Change Type (select all) - [x] Bug fix - [ ] Feature - [ ] Refactor - [ ] Docs - [x] Security hardening - [ ] Chore/infra ## Scope (select all touched areas) - [x] Gateway / orchestration - [ ] Skills / tool execution - [ ] Auth / tokens - [ ] Memory / storage - [ ] Integrations - [x] API / contracts - [ ] UI / DX - [ ] CI/CD / infra ## Linked Issue/PR - Closes # (none filed yet — discovered via real-world data loss incident) ## User-visible / Behavior Changes - `agents delete` now logs `Skipping workspace deletion — shared with: <agent-ids>` when the workspace is used by other agents, instead of silently trashing it. - No behavior change when workspace is unique to the deleted agent (still trashed as before). ## Security Impact (required) - New permissions/capabilities? `No` - Secrets/tokens handling changed? `No` - New/changed network calls? `No` - Command/tool execution surface changed? `No` - Data access scope changed? `No` - If any Yes, explain risk + mitigation: N/A — this PR prevents data loss by checking workspace ownership before deletion. ## Repro + Verification ### Environment - OS: macOS - Runtime/container: Node.js (OpenClaw 2026.2.14+) - Model/provider: N/A (CLI/gateway behavior) - Integration/channel (if any): N/A - Relevant config (redacted): Two agents configured with same `workspace` path in `openclaw.json` ### Steps 1. Register two agents with the same workspace: `openclaw agents add agentA --workspace ~/Projects` and `openclaw agents add agentB --workspace ~/Projects` 2. Delete one: `openclaw agents delete agentA --force` 3. Check `~/Projects` — it has been trashed. ### Expected - agentA's agent config dir and sessions dir are trashed - Shared workspace (`~/Projects`) is preserved since agentB still uses it ### Actual - `~/Projects` is trashed along with agentA's config — agentB's workspace is destroyed ## Evidence - [x] Failing test/log before + passing after - [ ] Trace/log snippets - [ ] Screenshot/recording - [ ] Perf numbers (if relevant) Test `"skips workspace deletion when workspace is shared with another agent"` fails before fix (workspace path found in trashed paths), passes after fix. ## Human Verification (required) - Verified scenarios: shared workspace (2 agents same path), unique workspace (agent with own path), default agent implicit check - Edge cases checked: agent pointing to default workspace path, agent list containing only the deleted agent - What you did **not** verify: Windows/Linux path resolution, non-`trash` fallback path (manual `.Trash` move) ## Compatibility / Migration - Backward compatible? `Yes` - Config/env changes? `No` - Migration needed? `No` ## Failure Recovery (if this breaks) - How to disable/revert this change quickly: Revert the single commit — the guard is additive - Files/config to restore: None - Known bad symptoms reviewers should watch for: Workspace directories not being cleaned up after agent deletion when they should be (false positive shared detection) ## Risks and Mitigations - Risk: False positive shared detection prevents legitimate workspace cleanup - Mitigation: Uses exact path matching (`===`) on fully resolved paths. Only truly shared workspaces are skipped. Users can manually trash the workspace after deletion if needed. --- - [x] Mark as AI-assisted in the PR title or description - [x] Note the degree of testing: fully tested (2 new unit tests + full suite green) - [x] Confirm understanding: all code understood by author 🤖 AI-assisted PR (Claude Code) — fully tested, all code understood by author <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds a shared-workspace guard to the agent deletion flow (both CLI and gateway). A new `isWorkspaceSharedByOtherAgent()` helper in `agent-scope.ts` checks whether any other registered agent (or the implicit default agent) shares the same resolved workspace path before deletion proceeds. Both `agents.commands.delete.ts` and the gateway `agents.delete` handler now skip workspace trashing when the path is shared. - The core logic is correct: both paths use the original config (pre-prune) for the sharing check, and `resolveAgentWorkspaceDir` normalizes paths via `path.resolve` making the `===` comparison reliable for non-symlinked paths. - The default agent implicit check covers the edge case where no agents are explicitly listed in the config. - Two new gateway-level tests validate the shared and non-shared scenarios. - Minor gap: the CLI's `--json` output doesn't indicate whether the workspace was actually deleted or skipped due to sharing, which could confuse programmatic consumers. <h3>Confidence Score: 4/5</h3> - This PR is safe to merge — it adds a defensive guard that prevents data loss without altering the happy path. - Score of 4 reflects that the core fix is correct and well-tested at the gateway level. The path comparison logic is sound for the common case. Deducted one point because: (1) the CLI's JSON output doesn't indicate workspace skip status, which is a minor API contract gap; and (2) `isWorkspaceSharedByOtherAgent` itself has no direct unit tests — it's only tested via mocked integration tests. - `src/commands/agents.commands.delete.ts` — JSON output should indicate whether workspace was skipped <sub>Last reviewed commit: 8634810</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs