Repository navigation
[Bug] A session is reclaimed mid-use and the borrowed tab's page state is lost, with no warning #386
Description
What happens
A session stopped existing while I was still working on it, and the page state
inside its Agent Window went with it.
- The session was alive and healthy; every command succeeded. I then spent a stretch
of time on something else (acargo build, roughly 20 minutes) without touching
the browser. - The next
bsk session listreturned(no active sessions). The Agent Window tab
was gone from the browser. - The tab held a half-filled 30-field application form. Nothing recovered it:
the site (Moka,app-tc.mokahr.com) keeps no server-side draft, and re-opening
the page gave a blank form. All of it had to be filled again.
Two things make this worse than a normal expiry:
- There is no warning and no signal. No command failed, no error was returned,
nothing was printed on the transition. The loss is only observable afterwards, as
an emptysession list. - The reason is not observable either. From the caller's side, a daemon that
exited (idle threshold — see [Feature] Please providebsk daemon install-autostart(and document the 10-minute idle exit) #337) and an extension that dropped the Agent Window
produce the same(no active sessions). Related: [Bug][dsh-plugin] start 未返回时残留无人认领的 Agent Window,DSH 侧任何路径都关不掉它 | unregistered Agent Window orphaned by a non-returning browser_session start #245 (an Agent Window that
cannot be closed from the DSH side).
I would not argue that sessions must live forever — but the default has to be
knowable before the work that depends on it.
Suggested fix
Any one of these would have prevented the loss:
bsk session listshowing the remaining lifetime / last activity, so the caller
can see the session is on a clock.- A way to say "I still need this" — a keepalive, or a per-session TTL option —
for work that is long but not browser-bound. (bsk statusalready reports daemon
state; the session is the thing that actually disappears.) - A distinct error reason on the next command after the loss, distinguishing
"daemon exited" from "Agent Window closed" from "extension disconnected", instead
of onesession not found. - If none of the above: documenting the exact reclaim rule in the README, because
the practical consequence — "an agent that thinks for 20 minutes loses the page" —
is not something a caller can infer.
Impact
Roughly 45 minutes of work, and a task that had to be restarted from zero. For any
caller driving a long form, this is the single highest-cost failure mode in the
current design; the per-command cost model is irrelevant next to it.
Environment
- bsk 0.3.2, built from source, Windows 11 Home China,
stable-x86_64-pc-windows-gnu - Edge, extension loaded from
apps/extension - Observed once in this session; the earlier Agent Window (session
yokv) never
came back andbsk session liststayed empty afterwards
中文摘要:会话在我仍在使用期间被回收,Agent Window 连同标签页里填了一半的 30 字段表单一起消失,站点不存草稿,全部白填(约 45 分钟)。全程没有任何报错或预警,bsk session list 直接变成 (no active sessions);而"daemon 空闲退出"(见 #337)和"扩展掉了 Agent Window"在调用方看来是同一种现象。建议:session list 暴露剩余寿命/最近活动,或提供 keepalive / TTL 选项,或至少用不同的错误原因区分这三种结束方式。
Activity
lmliheng commentedon Oct 1, 2026
Second occurrence, and this one rules the daemon out as the cause.
dyrrwas healthy and in active use at 22:35 local time; the nextbsk session list --jsonat 22:52 returned[].bsk status --jsonreported:pid 223012,uptime_secs 7182(~2 h),browsers[0]=edge 154.0.0.0,instance_id be16dfae.disappeared, after roughly 17 minutes in which no command was issued against it.
page it had borrowed is gone with it.
This makes the "daemon idle exit (#337)" explanation insufficient for this case —
the reclaiming is happening at the session layer while both the daemon and the
browser connection are alive. The part that still hurts is that neither the loss
nor its cause is observable: every other command keeps succeeding, and the caller
only finds out at the next
bsk session list.If it helps to reproduce: Windows 11 + Edge,
bsk0.3.2 built from source, theborrowed tab sitting on an ordinary https page (a Moka application form), idle for
~15-20 minutes with the Agent Window left open in the background.
lmliheng commentedon Oct 1, 2026
Correction to my comment above — the daemon log does record why a session ended,
and I attributed the second occurrence to the wrong cause. I should have read
bsk logsbefore writing.I now have the daemon's own log (timestamps UTC; local = UTC+8):
Two corrections:
per cause.
idle session stoppedis a session-level idle timeout — separatefrom the daemon's own 600 s idle exit — and
cpgi,tvkd,gffx,dxzsandyokvall ended that way. My claim that "the reason is not observable either"was wrong.
use. For session
dyrrthe daemon loggedsession removed: user closed Agent Window— the Agent Window was closed, sothat is not a bug. What I actually observed at the time (daemon alive, Edge
connected,
session listempty) was equally consistent with both causes, and Idrew the wrong conclusion from it. I withdraw that part of the comment.
What still stands, and is why this issue is open: sessions
cpgi,tvkd,gffx,dxzsandyokvwere stopped by the idle timeout while the browser was stillconnected and without anything telling the caller beforehand, and the state of
the borrowed page went with them — for
yokvthat was roughly 45 minutes of workon a form that keeps no server-side draft.
So the gap is not "the reason is unrecorded". It is that the reason is recorded
where the caller does not look, and cannot be seen before it happens:
bsk session listexposes no lifetime or last-activity, so nothing tells acaller that a session is on a clock;
bskcommand only sayssession not registered or already stopped— it does not carry the reason thatthe log already has;
The feature request is unchanged, just better aimed: surface the existing
idle-stop reason and the remaining lifetime at the session layer, instead of
leaving them in the log file. If the answer is "the log is the interface", then
bsk session list/ the failure error should point at it — that alone would havesaved me from filing the wrong half of this report.
XY-code1 commentedon Oct 16, 2026
Hi, I’m interested in working on this issue. I noticed that #456 appears to describe the same session idle-time problem.
I’d like to start with a minimal, backward-compatible scope:
Before implementation, could you confirm whether this direction matches the intended session lifecycle design, and whether configuration should be global or per-session?
XY-code1 commentedon Oct 16, 2026
Hi! I investigated the current implementation and would like to contribute a focused fix.
I confirmed that the daemon already supports a global
--session-idletimeout, but session activity is currently refreshed only by accepted/completed BrowserSkill tool calls. Manual interaction in the borrowed browser tab does not refresh the session, so an actively edited form can still be reclaimed after the timeout.I see two possible directions:
To keep the change backward-compatible, which direction would you prefer? If manual browser activity should count, I can prepare a small implementation with regression coverage. If not, I can focus on lifecycle visibility/documentation and tests around the existing
--session-idleconfiguration.