You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
/Undo command does not work if last user message gets out of visible session history #28257
If the agent gets stuck in a loop and last user message is no longer visible in the scroll-history, /undo command does not work
It should work regardless of visible message history
Plugins
No response
OpenCode version
1.14.50
Steps to reproduce
Send a message
Wait for the history to get filled with agent messages and last user message disappear from history
Root cause
The TUI's undo/redo commands searched sync.data.message[sessionID], an in-memory message cache capped at 100 entries per session. When an agent loop generates enough assistant/tool messages to push the total past 100, the oldest user messages get shifted out. /undo then silently fails because it can't find earlier user messages.
Why TUI fails but Web UI works: The web UI doesn't maintain a capped local message cache — each request fetches complete history from the database. The TUI caps messages at 100 (for performance), but undo depended on that trimmed cache instead of fetching from the server.
Fix
Both undo and redo handlers now call sdk.client.session.messages() to fetch complete message history from the server, then find the target user message. For prompt restoration, a fallback handles entries that were still trimmed.
Files changed
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx — undo (line 598) and redo (line 637) handlers now fetch from server
packages/opencode/test/session/revert-trimmed-cache.test.ts — new test verifying sequential revert/unrevert works with 100+ messages
Still reproducible on v1.17.9. Confirming the root cause @lexlian identified: the TUI loads messages via client.session.messages({ sessionID, limit: 100 }) (packages/tui/src/context/sync.tsx), and the conversation view renders only sync.data.message[sessionID] (packages/tui/src/routes/session/index.tsx). session.first is just scroll.scrollTo(0) — pure viewport scroll, no cursor-based loadMore. So once a session exceeds ~100 messages, /undo can't reach targets outside that window, and there's no config to raise the cap (the limit: 100 is a hardcoded literal). The data is fully intact in opencode.db; it's purely a client-side load/window issue. Would really appreciate getting PR #28660 reviewed/merged.
Activity
github-actions commentedon May 18, 2026
This issue might be a duplicate of existing issues. Please check:
If your issue is distinct from these, no action needed — just wanted to flag the overlap.
remixer-dec commentedon May 18, 2026
to be more specific in reproducibility: I wanted to /undo 2 times, but only 1 was available since 2nd message disappeared from visible history
remixer-dec commentedon May 18, 2026
as a workaround for now: switch to a web version and do it there
lexlian commentedon May 27, 2026
I fixed the issue with PR #28660.
Root cause
The TUI's undo/redo commands searched sync.data.message[sessionID], an in-memory message cache capped at 100 entries per session. When an agent loop generates enough assistant/tool messages to push the total past 100, the oldest user messages get shifted out. /undo then silently fails because it can't find earlier user messages.
Why TUI fails but Web UI works: The web UI doesn't maintain a capped local message cache — each request fetches complete history from the database. The TUI caps messages at 100 (for performance), but undo depended on that trimmed cache instead of fetching from the server.
Fix
Both undo and redo handlers now call sdk.client.session.messages() to fetch complete message history from the server, then find the target user message. For prompt restoration, a fallback handles entries that were still trimmed.
Files changed
D1ChangGeng commentedon Jun 24, 2026
Still reproducible on v1.17.9. Confirming the root cause @lexlian identified: the TUI loads messages via
client.session.messages({ sessionID, limit: 100 })(packages/tui/src/context/sync.tsx), and the conversation view renders onlysync.data.message[sessionID](packages/tui/src/routes/session/index.tsx).session.firstis justscroll.scrollTo(0)— pure viewport scroll, no cursor-based loadMore. So once a session exceeds ~100 messages,/undocan't reach targets outside that window, and there's no config to raise the cap (thelimit: 100is a hardcoded literal). The data is fully intact inopencode.db; it's purely a client-side load/window issue. Would really appreciate getting PR #28660 reviewed/merged.github-actions commentedon Aug 24, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.