Repository navigation
Description
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()defaultslimitto 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
Activity
github-actions commentedon Mar 6, 2026
This issue might be a duplicate of existing issues. Please check:
opencode sessionscommand fails to list historical sessions when run inside a Git repository #15678:opencode sessionscommand fails to list historical sessions when run inside a Git repository — same symptom (missing historical sessions)You may also want to coordinate with the assignees on those issues to avoid duplicate work.
dinhphieu commentedon Mar 6, 2026
To add more context, this used to work just fine around 1-2 weeks ago. So a recent release must have changed the behaviour I guess
CasualDeveloper commentedon Apr 2, 2026
@dinhphieu can you check #13877 and see whether that problem is same as the one you're reporting here? we should probably consolidate this into that one, if yes
nigel-dev commentedon Apr 16, 2026
Hit by this on v1.4.6 — confirming same root cause.
Environment:
Symptom: TUI
/sessionsshows only 4 root sessions (all from today). All 86 older roots — including labeled conversations from the last month — are invisible.Confirmed mechanism: Exactly as described in the original report.
In
packages/opencode/src/cli/cmd/tui/context/sync.tsxat v1.4.6 (line 356-358):No
roots: true, so the server'slimit: 100gets saturated by subagent children. In my case:time_updated: 96 children, 4 roots.filter(x => x.parentID === undefined)→ 4 visibleThe moment you use subagents heavily (oh-my-opencode, explore/oracle/librarian agents, etc.), the child:root ratio blows out and the TUI session list becomes effectively useless.
Workaround: Bump
time_updatedon root sessions so they all fit in the top-100 window:Destructive to original ordering data but immediate relief.
Also relates to #13877, #16733, #17389.
jiwangyihao commentedon Apr 18, 2026
I opened PR #23276 to address the child-session dilution path discussed here: #23276
It fixes the same confirmed root cause (mixed root+child session list getting limited before root filtering), but I scoped the change to
dialog-session-list.tsxinstead of changing the global bootstrap insync.tsx.Reason for the narrower patch: after tracing current
dev,sync.data.sessionis also used by TUI session-parent / session-child navigation, so changing the shared bootstrap list to roots-only would affect a wider surface area. This PR keeps child-session data available for those flows while makingSwitch Sessionrequest root sessions directly for both the default list and search.The repro I used locally matched the pattern in this issue: the missing root session was rank 4 among root sessions but rank 152 among all sessions because 148 newer child sessions came first.
codeg-old commentedon May 9, 2026
I opened #26432 for this.
It avoids the earlier broad-bootstrap side effect by leaving the shared
sync.data.sessionlist unchanged and querying root sessions only inside the session switch dialog. It also avoids the 30-day bootstrap window for the default dialog list, preserves the existing scope/path filter, and includes a focused unit test for the query shape.Verified locally on the current
devbase with:bun test test/cli/tui/dialog-session-list.test.ts test/server/session-list.test.ts test/server/httpapi-sdk.test.ts --timeout 30000bun run typecheckbun run buildAuthorship disclosure: prepared with AI assistance.
EdgarSedov commentedon May 30, 2026
#26432 seems to address this without changing the shared bootstrap list, so it avoids the broader TUI parent/child session navigation concern from earlier fixes.
antomicblitz commentedon Jun 6, 2026
The web UI has this same bug, and the in-flight fix #26432 is TUI-only — it won't cover the web client.
Confirmed on opencode 1.16.2 (
opencode serve, accessed from a browser/phone). The web client fetchesGET /sessionwithoutroots=trueand filters children client-side (sessions.filter(s => !s.parentID)). So the server's defaultlimit=100is spent on a mix of root + subagent sessions, and roots get evicted under heavy subagent use — the same root cause described here.Measured on a store with 241 root + ~1032 child sessions:
Only 36 of 241 roots reach the web UI, and during multi-agent bursts (last 24h here: 59 child updates vs 6 root, ~10:1) even freshly-created root sessions drop out of the window within hours and never reappear (
time_updatednow below the 100th-newest). Data is intact on disk throughout.Since #26432 only touches the TUI dialog, please also have the web session list pass
roots=true(the API already supports it). Happy to test a build.12 remaining items
fix(tui): load root sessions in session switcher (#33931)
fix(tui): load root sessions in session switcher (anomalyco#33931)
fix(tui): load root sessions in session switcher (anomalyco#33931)
sync: merge upstream/dev catch-up (629 commits) (#31)
fix(test): resolve shell/cwd unit-test failures surfaced by GitHub-ho…
wsaaaqqq commentedon Jul 27, 2026
Same issue here — subagent dilution eating all the root sessions from the list.
Built a workaround: oos
It reads the OpenCode SQLite db directly, so it searches ALL sessions from
ALL projects at once — no directory scoping, no pagination limits, no
subagent dilution.
https://github.com/wsaaaqqq/oos
MIT, one-liner install. Happy to take feedback.
fix(tui): load root sessions in session switcher (#33931)
fix(tui): load root sessions in session switcher (anomalyco#33931)