What happened
Rewinding a TUI session via Esc Esc -> Rewind shows a transient Note: 正在回退到该轮之前… and then fails with the generic:
Error: Session conversation copy could not be committed
The message is produced by the single empty catch in packages/runtime-host/src/server/session-revision-coordinator.ts:540 / dist/.../session-revision-coordinator.js:382:
try {
await artifacts.copyConversationArtifacts(...)
await cloneConversationRuntimeLedger(...)
await taskLedger.copyConversationTaskLedger(...)
await sessionStore.appendMessages(...)
await sessionStore.updateHeader({state:'committed'})
await continuity.refreshCanonical(...)
} catch {
return rollbackIncompleteCopy('Session conversation copy could not be committed')
}
The original exception (e.stack / e.code) is discarded. The TUI (packages/cli/src/pi-tui-runner.ts:1768 + runtime-host-session-driver.ts:684 session.revision.create) only sees persistence_failed and cannot distinguish:
SQLITE_BUSY / wal contention during appendMessages
archived tool result hash mismatch after copyConversationArtifacts
owned references inside archived tool results / continuation authority rewrite failures
SQLITE_FULL / permission errors
from the expected session_busy: Source Session has an active Turn that is correctly returned in the validation phase (coordinator.ts:355).
As a result, en already reproduces at the default panel measure min(680px, calc(100% - 32px)) without any narrowing — two graph_record_* ids are sufficient at 680px. zh (one character per line) is the louder symptom, but the root shrink is the same. Captured at both 430px and 980px in #3970 for the related UI issue, but the Host-side swallowing is independent and affects all locales (UI_LOCALES = ['zh','en']).
How to reproduce
- Start TUI
maka on main (07e40fe, Linux, Node 26.3.0) with workspace ~/.config/Maka/workspaces/default.
- Use a session that has at least two
user turns and at least one large archived tool result (e.g., e2dbda6e-336b-... with turns c64163d9 and 1252e2dd / graph_record_* artifacts, or any session with Agent Graph 8/8 operators).
- Ensure the session is
idle (session.catalog.query kind:get shows status: idle and empty liveRunState.runningTurnIds). If running, the expected session_busy is returned — this is not the bug.
- In TUI, press
Esc Esc, select any earlier turn (e.g., 1252e2dd before 创建issue).
- Observe the transient
正在回退... notice, then Error: Session conversation copy could not be committed with no further details. With a patched Host that logs catch(e), /tmp/rewind-error.log shows the real e.stack (e.g., SQLITE_BUSY or hash mismatch).
Stable reproduction on main when the source session is idle but its copyTurnIds contain large archives or taskLedger contention. A fresh single-turn session with no archives rewinds successfully, proving the failure is data-dependent, not environment.
Environment
- Maka version or commit:
main @ 07e40fe (2026-08-27)
- OS and version: Linux
- Surface: TUI (
maka CLI) + Runtime Host
- Node.js version: 26.3.0
- Workspace:
~/.config/Maka/workspaces/default (runtime.sqlite 1.1G, runtime.sqlite-wal 17M)
Logs, screenshots, or additional context
- TUI screen:
Note: 正在回退到该轮之前… followed by Error: Session conversation copy could not be committed (from pi-tui-runner.ts: rewindToTurn).
- Direct Host call also reproduces:
await conn.request('session.revision.create', {
sourceSessionId: 'e2dbda6e-336b-4d65-8e7f-13453b106339',
targetSessionId: 'test-rewind-...',
sourceTurnId: '1252e2dd-d065-4784-9573-e07579c8efba',
expectedSourceRevision: 98
})
// -> RuntimeHostOperationError: Session conversation copy could not be committed
// with swallowed cause
What happened
Rewinding a TUI session via
Esc Esc -> Rewindshows a transientNote: 正在回退到该轮之前…and then fails with the generic:The message is produced by the single empty
catchinpackages/runtime-host/src/server/session-revision-coordinator.ts:540/dist/.../session-revision-coordinator.js:382:The original exception (
e.stack / e.code) is discarded. The TUI (packages/cli/src/pi-tui-runner.ts:1768+runtime-host-session-driver.ts:684session.revision.create) only seespersistence_failedand cannot distinguish:SQLITE_BUSY/walcontention duringappendMessagesarchived tool result hash mismatchaftercopyConversationArtifactsowned references inside archived tool results/continuation authorityrewrite failuresSQLITE_FULL/ permission errorsfrom the expected
session_busy: Source Session has an active Turnthat is correctly returned in the validation phase (coordinator.ts:355).As a result,
enalready reproduces at the default panel measuremin(680px, calc(100% - 32px))without any narrowing — twograph_record_*ids are sufficient at 680px.zh(one character per line) is the louder symptom, but the root shrink is the same. Captured at both 430px and 980px in #3970 for the related UI issue, but the Host-side swallowing is independent and affects all locales (UI_LOCALES = ['zh','en']).How to reproduce
makaonmain(07e40fe, Linux, Node 26.3.0) with workspace~/.config/Maka/workspaces/default.userturns and at least one large archived tool result (e.g.,e2dbda6e-336b-...with turnsc64163d9and1252e2dd/graph_record_*artifacts, or any session withAgent Graph8/8operators).idle(session.catalog.query kind:getshowsstatus: idleand emptyliveRunState.runningTurnIds). Ifrunning, the expectedsession_busyis returned — this is not the bug.Esc Esc, select any earlierturn(e.g.,1252e2ddbefore创建issue).正在回退...notice, thenError: Session conversation copy could not be committedwith no further details. With a patched Host that logscatch(e),/tmp/rewind-error.logshows the reale.stack(e.g.,SQLITE_BUSYor hash mismatch).Stable reproduction on
mainwhen the source session isidlebut itscopyTurnIdscontain large archives ortaskLedgercontention. A fresh single-turn session with no archives rewinds successfully, proving the failure is data-dependent, not environment.Environment
main @ 07e40fe(2026-08-27)makaCLI) + Runtime Host~/.config/Maka/workspaces/default(runtime.sqlite1.1G,runtime.sqlite-wal17M)Logs, screenshots, or additional context
Note: 正在回退到该轮之前…followed byError: Session conversation copy could not be committed(frompi-tui-runner.ts: rewindToTurn).catch {tocatch (e) { logger.error({err:e, sourceSessionId, targetSessionId}, 'revision copy commit failed'); return rollbackIncompleteCopy('...: ' + e.message) }and split the 7 steps into distinct error codes (artifact_copy_failed,runtime_ledger_failed,task_ledger_failed) so the TUI can surface the specific reason. Keepsession_busyas the early validation path.session-revision-coordinator.bug