Empty per-conversation scratch directories accumulate in the scratch base and are never cleaned up
Summary
OpenCoworker creates a per-conversation scratch directory under the configured scratch base (default ~/OpenCoworker) for every cowork session, but never removes it — even when the conversation writes no files and even after the session is deleted. Over normal use the base fills with empty UUID-named folders.
Environment
- OpenCoworker desktop (
platform/), macOS - Default agent (cowork), no project folder bound
Steps to reproduce
- Complete onboarding, choosing a scratch folder (e.g.
~/OpenCoworker). - Start a few cowork conversations that only chat (no file-producing tasks).
- Optionally delete some of those conversations in the UI.
- Open the scratch folder in Finder.
Expected: the folder reflects actual agent output; conversations that produced no files leave nothing behind, and deleting a conversation removes its (empty) scratch dir.
Actual: one empty <12-char-session-id>/ directory per conversation, persisting indefinitely; deleting the conversation does not remove it.
Root cause
SessionManager._provision_scratch(platform/coworker/server/manager.py) eagerlymkdirs the scratch dir, called fromget_enginewhen a cowork session starts.get_rootsalso calls_provision_scratchas a side effect, so merely inspecting a session's roots re-creates the directory.delete_sessionremoves the session row but never touches the scratch dir on disk.
Note for others hitting this (it is not data loss)
Conversations and memory persist in the app-data dir (~/.config/coworker/ — coworker.db + conversations/*.jsonl), not in the chosen scratch base. The scratch base only ever holds files the agent explicitly writes during a task. The empty folders are harmless litter, but they're confusing — several users may read "my chosen folder is empty" as "my work wasn't saved."
Proposed fix
Conservative, in priority order:
- On
delete_session, remove the session's scratch dir only if it exists, is empty, and its name matches the session id (never recurse, never delete a dir containing agent output). - Stop
get_rootsfrom creating the dir as an inspection side effect — return the intended path withexists: falseinstead. - (Optional) Provision the scratch dir lazily on first write rather than at engine build, so chat-only conversations never create one.
Happy to open a PR with (1) + (2) plus tests. Would you prefer cleanup-on-delete, lazy provisioning, or both? I'd also clarify the storage-location distinction in the onboarding copy if that's welcome.
Source: andrewyng/aisuite