session: a suspended session never gets time_idle and stays 'running' in the sidebar forever

Aperta
#62,779 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

  • #62791 di @hakarrr — chiusa senza merge

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
35/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
sqlite, typescript
Ambito
backend, databases

Direzione di ricerca

Start by tracing the code that writes time_suspended and the sidebar logic that counts child sessions with time_idle unset; the issue does not name files or tests. Check how startup or suspension handles sessions without a live process or turn, then add coverage for a suspended child. Done means interrupted children are finalized and no longer counted as running.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

reproduced

Summary

A session that is suspended by a server restart (or otherwise interrupted) never gets time_idle / idle_outcome written. The sidebar therefore counts it as an active subagent indefinitely — in my case the app showed "6 subagents" while only 2 were actually running; the other four had last activity 4 and 10 days earlier. Only a manual UPDATE session_v2 SET time_idle = ... clears them.

Environment

  • opencode version: v2.1.4
  • OS: Linux 6.17.0-41-generic (Ubuntu) x86_64
  • Terminal: TERM_PROGRAM=WezTerm, TERM=xterm-256color, COLORTERM=truecolor
  • Shell: /usr/bin/zsh
  • Install/channel: latest (~/.opencode/bin/opencode)
  • Active plugins: none found in ~/.config/opencode/opencode.json (permissions only) and no .opencode/plugin* directories

Reproduction

  1. Run opencode with a main session that spawns subagent sessions (the child rows have session_v2.parent_id set).
  2. Restart the app/server, or let the server suspend a child while it is running (in my DB these rows have time_suspended set).
  3. Open the session sidebar / subagent counter.
  4. Observe the suspended child still counted as running, days after its last message.
  5. Confirm in the database: the row has time_suspended set, but time_idle IS NULL and idle_outcome IS NULL.

Query used:

select id, title, time_updated, time_idle, time_suspended, idle_outcome
from session_v2
where parent_id = '<main session id>' and time_idle is null
order by time_updated desc;

Result at the time of the report (only the first two were actually alive):

last activity title time_idle time_suspended
today 21:51 Multi-instance processor and drain NULL set
today 21:45 Fix macOS desktop compile stage NULL set
2026-11-04 13:21 Scrub client infrastructure NULL set
2026-11-04 13:07 Fix code-diver index freshness NULL set
2026-11-04 01:45 Infisical env gap and config guard NULL set
2026-10-27 19:40 Ask-for-credentials UX with reuse NULL NULL

Expected Behavior

A child session that the server suspends or abandons should be finalized — time_idle written with idle_outcome of interrupted/failed — so the UI stops counting it as an active subagent. At minimum, a session with no activity for hours/days must not be reported as running.

Actual Behavior

The sessions keep time_idle IS NULL forever. The subagent counter and any "running" indicator treat them as live work: the UI said "6 subagents" when 2 were running and 4 had been dead for 4-10 days. Restarting the app does not reconcile them, because the state lives in the database, not in memory.

Scale in this one profile: 1896 rows in session_v2, of which 761 had time_idle IS NULL (most inherited from the v2 migration), so this is systematic rather than a one-off.

Additional Context

Workaround that fixed the display (data-preserving, only marks sessions idle):

update session_v2
set time_idle = time_updated, idle_outcome = 'interrupted'
where time_idle is null
  and time_updated < (strftime('%s','now') - 24*3600) * 1000;

After that the sidebar showed only the two genuinely running subagents.

Expected repair path inside opencode: on startup (or on the suspension path that sets time_suspended), finalize any child that has no live process/turn — e.g. mark time_idle = time_updated, idle_outcome = 'interrupted', and expose that state in the sidebar instead of "running".

Lingua principale
TypeScript
Stelle
225k
Fork
30.4k
Merge medio
4h 16m
PR unite (30g)
528

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di anomalyco/opencode

Tutte le issue di anomalyco/opencode

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.