Skip to content

fix(opencode): clear session status before publishing status events - #14225

Merged
marius-kilocode merged 2 commits into
mainfrom
fix/stale-session-status-blocks-reload
Sep 17, 2026
Merged

marius-kilocode merged 2 commits into
mainfrom
fix/stale-session-status-blocks-reload

Conversation

@marius-kilocode

Copy link
Copy Markdown
Collaborator

What Problem This Solves

/reload can report "Cannot reload while a session is running in this project" when no session is running. The block persists until the backend restarts.

Why This Change Was Made

Session status cleanup ran after event publication:

  1. The session runner stops and calls SessionStatus.set(id, { type: "idle" }).
  2. The handler publishes session.status and session.idle.
  3. Only then does it clear the busy entry from the local and project-scoped stores.

Event listeners run inline without failure isolation. If a listener fails during step 2, step 3 never runs. The runner is gone, but the project status store still lists the session as busy, and SessionStatus.listAll() keeps returning that entry to the reload guard added in #12454.

The fix applies all status map mutations before publishing. Listeners now observe the settled status, and a failing listener can no longer leave a stopped session busy.

User Impact

Reload works after a session stops even when a status listener fails. A session that is still running blocks reload as before.

Evidence

  • New regression tests in packages/opencode/test/kilocode/session-status.test.ts cover successful idle publication and deliberate listener failures on both session.status and session.idle. Each asserts that list() and listAll() no longer contain the busy entry, both during and after publication.
  • bun test test/session/status.test.ts test/kilocode/session-status.test.ts test/kilocode/instance-reload.test.ts test/kilocode/instance-store-project-reload.test.ts: 17 passed.
  • bun run typecheck in packages/opencode: passed.
  • bun run compile in packages/kilo-vscode: passed.
  • Isolated VS Code self-test with two disposable repositories, multi-project enabled, and a deterministic local provider: reload succeeded with both projects idle, after session completion, and after cancellation, and was correctly blocked while a session was running.

Limitation: the reported multi-project incident was not reproduced on an unpatched build. This addresses a confirmed stale-status failure path rather than proving the original report's exact trigger.

Reload refused to run when a stopped session was still marked busy. The
session runner removed its entry, then published idle notifications, and
only then cleared the busy status. A failing event listener aborted the
clear, so the completed session stayed busy in the project status store
and every later reload returned 409.

Apply status map mutations first, then publish. Listeners now observe the
settled status, and a listener failure can no longer block reload for a
session that already stopped.
Comment thread packages/opencode/src/session/status.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • packages/opencode/src/session/status.ts
  • packages/opencode/test/kilocode/session-status.test.ts
Previous Review Summary (commit 88d2315)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 88d2315)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/session/status.ts 101 Non-idle status is now written before publishing, so a failing listener leaves a permanently stale busy entry. The startShell path awaits onBusy before forking (so onIdle never runs), and cancel does not clear it — /reload stays blocked until restart.
Files Reviewed (3 files)
  • .changeset/fix-stale-reload-status.md - 0 issues
  • packages/opencode/src/session/status.ts - 1 issue
  • packages/opencode/test/kilocode/session-status.test.ts - 0 issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

Moving the non-idle publication after the map writes created a new
permanent-busy path. A failing status listener left the entry in data,
stores, and byDirectory before SessionRunState.startShell forked its
shell. startShell awaits onBusy first, so no shell ran, no onIdle fired,
and the project store kept the session busy until a backend restart.

Publish the status event before mutating the map on the busy path, as the
original code did. The idle path still clears first, which is what keeps a
stopped session from blocking reload. Add a busy-path regression test with
a failing listener.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants