Skip to content

[FEATURE]: Subagent sessions accumulate without cleanup option - causes storage bloat and UI clutter #5734

@NachoFLizaur

Description

@NachoFLizaur

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Summary

Subagent sessions (spawned via the Task tool / @agent mentions) accumulate in storage and the session switcher UI (ctrl+x left/right) without any automatic cleanup or manual deletion option. This causes:

  1. UI clutter - Session switcher fills with completed subagent sessions
  2. Storage bloat - Session data, messages, and parts accumulate indefinitely
  3. Errors on manual deletion - Deleting session files directly causes "Session not found" errors due to orphaned data

Environment

  • OpenCode Version: 1.0.164
  • OS: macOS (also affects Linux)
  • Terminal: Any

Steps to Reproduce

  1. Start OpenCode in any project
  2. Use the Task tool multiple times (e.g., @code-explorer find all files related to...)
  3. Complete several subagent tasks
  4. Press ctrl+x left or ctrl+x right to view sessions
  5. Observe: Completed subagent sessions accumulate with no way to close/delete them
  6. Check storage: ls ~/.local/share/opencode/storage/session/global/
  7. Observe: Subagent session files keep accumulating

Expected Behavior

  • Completed subagent sessions should either be auto-cleaned or have a UI option to close/delete
  • Deleting a session should clean up all related data (messages, parts, diffs)

Actual Behavior

  • Subagent sessions persist indefinitely
  • No UI option to close or delete them
  • Manual file deletion causes orphaned data and "Session not found" errors

Root Cause Analysis

When a subagent is spawned, OpenCode creates multiple related data files:

~/.local/share/opencode/storage/
├── session/<project>/ses_xxx.json      # Session metadata (has parentID field)
├── message/ses_xxx/                     # Messages for the session
├── part/msg_xxx/                        # Message parts (tool calls, etc.)
└── session_diff/ses_xxx.json           # File change tracking

Key identifier: Subagent sessions have a parentID field in their JSON:

{
  "id": "ses_xxx",
  "parentID": "ses_parent",  // <-- This indicates it's a subagent
  "title": "Task description (@agent-name subagent)"
}

When manually deleting only the session file, the message/, part/, and session_diff/ data becomes orphaned, causing the "Session not found" error when the UI tries to access them.

Workaround

Option A: Custom OpenCode Command

Create a custom command at ~/.config/opencode/command/cleanup-subagents.md:

cleanup-subagents.md

---
description: Clean up completed subagent sessions for current project
---

Clean up all completed subagent sessions. These are child sessions spawned by the Task tool that accumulate over time.

## Task

Execute the cleanup based on the scope argument:
- Default (no args): Clean current project's subagents only
- `all`: Clean ALL subagent sessions (global + all projects)  
- `global`: Clean only global subagents
- `list`: Just list subagent sessions without deleting

## Step 1: Identify Current Project

First, check what projects exist and find the current one:

!`cat ~/.local/share/opencode/storage/project/*.json 2>/dev/null | grep -E '"(id|worktree)"' | paste - - | head -20`

## Step 2: Determine Scope

The user's argument is: `$ARGUMENTS`

Based on this:
- If empty or "project": Find the project matching the current working directory and clean only that
- If "global": Clean only `~/.local/share/opencode/storage/session/global/`
- If "all": Clean all session directories
- If "list": Just show what would be deleted

## Step 3: Execute Cleanup

For the determined scope, run the cleanup script. Here's the pattern:

```bash
cd ~/.local/share/opencode/storage

# For each target directory (e.g., session/global/ or session/<project-hash>/)
# Find sessions with parentID (subagent sessions)
for f in session/<TARGET>/*.json; do
  if grep -q '"parentID"' "$f" 2>/dev/null; then
    ses_id=$(basename "$f" .json)
    # Delete: session file, message dir, session_diff
    rm -f "$f"
    rm -rf "message/${ses_id}"
    rm -f "session_diff/${ses_id}.json"
  fi
done

# Clean orphaned part directories
for part_dir in part/msg_*/; do
  msg_id=$(basename "$part_dir")
  # Check if any message dir references this
  found=$(find message -name "${msg_id}.json" 2>/dev/null | head -1)
  [ -z "$found" ] && rm -rf "$part_dir"
done
```

## Step 4: Report Results

After cleanup, report:
1. How many subagent sessions were deleted
2. How many orphaned part directories were cleaned
3. Remaining session count

## Important

- ONLY delete sessions with `"parentID"` field - these are subagents
- Sessions WITHOUT parentID are main conversations - NEVER delete these
- Storage path: `~/.local/share/opencode/storage/`
```

Then use it with:

/cleanup-subagents          # Clean current project
/cleanup-subagents all      # Clean all projects  
/cleanup-subagents global   # Clean only global
/cleanup-subagents list     # List without deleting

Option B: Standalone Bash Script

#!/bin/bash
cd ~/.local/share/opencode/storage

# Delete subagent sessions (those with parentID)
for f in session/*/*.json; do
  if grep -q '"parentID"' "$f" 2>/dev/null; then
    ses_id=$(basename "$f" .json)
    rm -f "$f"
    rm -rf "message/${ses_id}"
    rm -f "session_diff/${ses_id}.json"
  fi
done

# Clean orphaned part directories
for part_dir in part/msg_*/; do
  msg_id=$(basename "$part_dir")
  found=$(find message -name "${msg_id}.json" 2>/dev/null | head -1)
  [ -z "$found" ] && rm -rf "$part_dir"
done

Suggested Fixes

Option 1: Auto-cleanup on completion
When a subagent task completes, automatically clean up its session data.

Option 2: Add UI controls

  • Add "Close" or "Delete" action in the session switcher for subagent sessions
  • Visual distinction between main sessions and subagent sessions
  • "Clean all completed subagents" bulk action

Option 3: Add built-in command

/cleanup-subagents    # Clean completed subagent sessions
/gc                   # Garbage collect orphaned data

Option 4: TTL-based cleanup
Configuration option for subagent session TTL:

{
  "subagent": {
    "sessionTTL": "24h"
  }
}

Metadata

Metadata

Assignees

Labels

discussionUsed for feature requests, proposals, ideas, etc. Open discussion

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions