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
Background tasks show as running in UI but disappear from /tasks after a non-graceful exit #3924
Bug: background tasks stuck as "running" in UI after the app exits, while /tasks can no longer find them
Repro
Start a long-running background task in a session (e.g. a shell command that sleeps).
Kill the app process abruptly (or let the machine reboot / the process die without graceful shutdown) — any exit path that does not go through the graceful session-close flow.
Reopen the app and look at the session in the web/desktop UI: the task still shows as running.
In the CLI, /tasks (or the REST endpoint GET /api/v1/sessions/{id}/tasks) reports nothing for that session.
Root cause
Task state lives in several places with no reconciliation between them:
The live registry (AgentTaskService) is scoped to the agent/session and disappears when the session is destroyed — so the CLI/cold REST endpoint legitimately see no tasks.
The wire log (wire.jsonl) records task.started as a durable event, but task.terminated is only written on the graceful-exit path (removeManaged -> stopAllOnExit -> flush). On a crash/kill the termination event is missing.
The UI reads tasks from the transcript projection. For a cold session this is rebuilt purely from wire.jsonl, so a task with a bare task.started and no task.terminated is reconstructed forever as state: 'running'.
Result: two views of the same task that permanently disagree — "running" in the UI, empty in /tasks.
Suggested fix
Two small, storage-layer-only changes:
kap-server cold transcript read (readColdSnapshot): a cold session's owner process is gone by definition, so any non-terminal task in the folded snapshot should be rewritten to a terminal state ('lost').
AgentTaskService.dispose: settle non-terminal entries to killed (reason: session closed) and persist, mirroring the graceful-exit path, so a hard kill does not leave bare task.started events in the wire log.
Both changes are scoped to the server side; the CLI and live-session paths need no changes.
Activity