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
OpenCode 2: every failed historian run leaves a new hidden session behind (114 in 2.5 h with a quota-exhausted provider) #481
On OpenCode 2 (2.0.7, magic-context 0.42.6) the historian's models were all unavailable for a while: the primary (opencode-go/gpt-5.6-luna) returned "Go usage limit exceeded" (weekly quota), and the fallback (opencode/muse-spark-1.3-contributor-free) returned "OpenCode's free tier can only be used from within OpenCode". Every historian run failed, and every failed run left a new Magic Context historian session behind: 114 sessions in about 2.5 hours in one project, all with 3–9 messages, all root sessions, so they fill the session list.
The project's hidden-children meta showed active: {} and 114 retired_children, every one with reason hidden-run-failed.
Why
In packages/plugin/src/v2/hidden-completion.ts:
close() retires the child on any failed run (hidden-run-failed).
open() also retires an active child whose newest assistant row is not a successful completion (newest-assistant-not-reusable), and then creates a new session.
A provider error (quota, rate limit, refused request) is persisted as a settled assistant row with error set. So a quota-exhausted provider guarantees a new child session per historian trigger until the quota resets, with nothing to clean the sessions up.
Why reusing the child is safe in this case
The hidden-child hook replaces the child's whole draft on every hidden prompt (draft.system, draft.messages = [calibrated request], draft.tools = {}). The error row is never sent to a model again, so a child whose only problem is a settled provider error is as good as a fresh one.
Proposed fix (PR to follow)
A run that failed only on settled provider-error rows keeps its child: no retire in close(), and open() accepts a child whose newest assistant is a settled provider error.
Every other failure keeps today's behaviour and retires the child: dispatch failures (a thrown prompt), refusals, timeouts and aborts.
A backoff for repeated provider errors would also stop the historian from re-trying a quota-exhausted pool on every trigger. That is a separate, larger change, so it is not part of this PR.
Activity
fix(opencode2): keep the hidden child after a settled provider error