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

Open
opened 2026-02-16 17:40:58 -05:00 by yindo · 1 comment
Owner

Originally created by @NachoFLizaur on GitHub (Dec 18, 2025).

Originally assigned to: @thdxr on GitHub.

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"
  }
}
Originally created by @NachoFLizaur on GitHub (Dec 18, 2025). Originally assigned to: @thdxr on GitHub. ### Feature hasn't been suggested before. - [x] 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: ```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](https://github.com/user-attachments/files/24232749/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 ```bash #!/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: ```json { "subagent": { "sessionTTL": "24h" } } ```
yindo added the discussion label 2026-02-16 17:40:58 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Dec 18, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #4980: Does OpenCode automatically clean up old session/conversation data? - Similar concern about session data accumulation and lack of automatic cleanup
  • #5667: LSPs keep accumulating, how do I remove them? - Related issue about resources accumulating in storage without cleanup mechanism

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Dec 18, 2025): This issue might be a duplicate of existing issues. Please check: - #4980: Does OpenCode automatically clean up old session/conversation data? - Similar concern about session data accumulation and lack of automatic cleanup - #5667: LSPs keep accumulating, how do I remove them? - Related issue about resources accumulating in storage without cleanup mechanism Feel free to ignore if none of these address your specific case.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#3640