#17488: fix(agents): skip workspace deletion when shared with other agents
gateway
commands
agents
stale
size: S
Cluster:
Workspace Path Fixes
## 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
#22917: fix: Use agent's configured workspace when spawned as subagent
by jriff · 2026-02-21
81.8%
#17757: fix(agents): resolve relative workspace paths against state dir, no...
by Phineas1500 · 2026-02-16
78.4%
#23085: fix(workspace): respect OPENCLAW_STATE_DIR for workspace paths, fix...
by charojo · 2026-02-22
76.6%
#19560: docs: refactor agent workspace default location & bootstrap configu...
by ashinkuniyil · 2026-02-17
75.8%
#2884: fix: Create memory directory and symlink identity files during work...
by webdevtodayjason · 2026-01-27
75.4%
#19482: fix(agents): only seed HEARTBEAT.md on brand-new workspaces
by CornBrother0x · 2026-02-17
74.7%
#19570: feat(workspace): core document change tracking — git-backed history...
by aronchick · 2026-02-17
74.2%
#4222: fix: canvas root should respect agents.defaults.workspace
by sanool · 2026-01-29
74.1%
#12956: fix: guard .trim() calls on potentially undefined workspaceDir
by omair445 · 2026-02-10
73.8%
#12939: fix(memory): strip null bytes from workspace paths causing ENOTDIR
by omair445 · 2026-02-09
73.6%