Description
The TUI /sessions picker only shows ~5 recent sessions despite having 584 root conversations in the DB going back to November 2025.
Root Cause
The TUI bootstrap in packages/opencode/src/cli/cmd/tui/context/sync.tsx calls:
const start = Date.now() - 30 * 24 * 60 * 60 * 1000
const sessionListPromise = sdk.client.session.list({ start: start })
This hits the /session endpoint, which calls Session.list() in packages/opencode/src/session/index.ts. Problem is child session dilution:
- Bootstrap does NOT pass
roots: true — mixes root sessions and child sessions (subagent forks)
Session.list() defaults limit to 100 (input?.limit ?? 100)
- Server returns 100 most recently updated sessions — roots + children mixed
- TUI dialog (
dialog-session-list.tsx) filters client-side: .filter(x => x.parentID === undefined)
- For users who spawn subagents/tasks heavily, children outnumber roots — 95 of 100 returned are children, only 5 roots visible
WorkspaceContext.workspaceID is undefined for TUI requests (no x-opencode-workspace header), so no filtering applied. Affects any user with child sessions (subagent forks, compaction, etc.) — higher child:root ratio = fewer roots shown.
Related: #13877 (same symptom), #15678
Evidence
- DB: 584 root sessions for my project, 8,976 total sessions (incl. children)
- In 30-day window: 2,501 child vs 255 root (9.8:1 ratio)
- Top 100 by time_updated (server return): 95 children, 5 roots
- Queried with:
sqlite3 ~/.local/share/opencode/opencode.db
Proposed Fix
One-line fix in sync.tsx bootstrap — add roots: true:
// Before:
const sessionListPromise = sdk.client.session.list({ start: start })
// After:
const sessionListPromise = sdk.client.session.list({ start: start, roots: true })
Server applies WHERE parent_id IS NULL server-side — all 100 slots go to actual conversations.
Alt: Bump limit or drop client-side filter (server handles it).
OpenCode version: 1.2.18
Steps to reproduce:
- Use OpenCode and spawn subagents / tasks heavily
- Open TUI and run
/sessions
- Notice only ~5 recent sessions appear despite hundreds existing
- Verify:
sqlite3 ~/.local/share/opencode/opencode.db "SELECT CASE WHEN parent_id IS NULL THEN 'ROOT' ELSE 'CHILD' END as type, COUNT(*) FROM (SELECT * FROM session ORDER BY time_updated DESC LIMIT 100) GROUP BY type;"
Operating System: Ubuntu 24.04.2 LTS (WSL2)
Terminal: xterm-256color / zsh
Description
The TUI
/sessionspicker only shows ~5 recent sessions despite having 584 root conversations in the DB going back to November 2025.Root Cause
The TUI bootstrap in
packages/opencode/src/cli/cmd/tui/context/sync.tsxcalls:This hits the
/sessionendpoint, which callsSession.list()inpackages/opencode/src/session/index.ts. Problem is child session dilution:roots: true— mixes root sessions and child sessions (subagent forks)Session.list()defaultslimitto 100 (input?.limit ?? 100)dialog-session-list.tsx) filters client-side:.filter(x => x.parentID === undefined)WorkspaceContext.workspaceIDis undefined for TUI requests (nox-opencode-workspaceheader), so no filtering applied. Affects any user with child sessions (subagent forks, compaction, etc.) — higher child:root ratio = fewer roots shown.Related: #13877 (same symptom), #15678
Evidence
sqlite3 ~/.local/share/opencode/opencode.dbProposed Fix
One-line fix in
sync.tsxbootstrap — addroots: true:Server applies
WHERE parent_id IS NULLserver-side — all 100 slots go to actual conversations.Alt: Bump limit or drop client-side filter (server handles it).
OpenCode version: 1.2.18
Steps to reproduce:
/sessionssqlite3 ~/.local/share/opencode/opencode.db "SELECT CASE WHEN parent_id IS NULL THEN 'ROOT' ELSE 'CHILD' END as type, COUNT(*) FROM (SELECT * FROM session ORDER BY time_updated DESC LIMIT 100) GROUP BY type;"Operating System: Ubuntu 24.04.2 LTS (WSL2)
Terminal: xterm-256color / zsh