[Bug]: ACP provider health probe creates a persistent empty OpenCode session on every refresh#25382

opened8d agobyFFrizi

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Configure T3 Code with the ACP Registry opencode-v2 provider enabled.
  2. Keep a T3 client connected so background provider-status work is allowed. Defaults: providerHealthRefreshInterval = 5 min; a successful probe is cached for 15 min (PROBE_SUCCESS_TTL_MS).
  3. Let T3 run for 15-30 minutes (or overnight).
  4. Inspect the OpenCode session list (opencode TUI, GET /api/session, or the SQLite DB).

Expected behavior

A provider health probe should be invisible to the user's OpenCode session history. If the probe must create a test session to validate the agent, it should delete that session before finishing — e.g. a best-effort runtime.deleteSession(sessionId) (or reuse of deleteAcpRegistrySession) guarded by sessionCapabilities.delete, with cleanup failures ignored. Sending session/close alone would not delete on 2.1.4; it only becomes useful once anomalyco/opencode#56088 ships.

Actual behavior

Every probe leaves a durable empty session in OpenCode:

  • title empty/NULL
  • agent empty, model empty
  • 0 message rows
  • version = "2.1.4" (T3's managed opencode-v2 binary)
  • cwd = the T3 server's cwd

At least 33 untitled, 0-message rows accumulated. They appear every ~15 minutes while T3 is in use (~4/hour) and persist until manually deleted. This is continuous, not occasional: every T3 session produces more rows, and real sessions get buried in the list.

The probe path is AcpRegistryDriver.checkProviderStatus → AcpRegistryProbe.probeConfiguration. packages/provider-acp-registry/src/server/probe.ts calls runtime.start() (ACP session/new in AcpSessionRuntime) with clientInfo.name = "t3-code-provider-test". When the probe's effect scope closes, AcpSessionRuntime terminates the ACP child process; the probe never sends session/close or session/delete. OpenCode persists the session eagerly on session/new (anomalyco/opencode#55293, anomalyco/opencode#38064), so the row survives. deleteAcpRegistrySession already exists in the same file (~line 646 on main), but it is wired only to user-initiated session management (driver.ts → AcpSessionManagementSection), not the probe path.

Impact

Major degradation or frequent failure

Version or commit

0.1.3-nightly.20261025.3692

Environment

Linux, T3 Code nightly desktop 0.1.3-nightly.20261025.3692, managed opencode-v2 2.1.4 (ACP), default "balanced" background activity profile; ACP Registry provider with agentId opencode-v2, distribution auto.

Logs or stack traces

shell
1# ~/.t3/userdata/logs/server.trace.ndjson
2# 16 AcpRegistryProbe.probeConfiguration spans; 03:04–06:19 exactly 900.0 s apart
302:59:02.825 probeConfiguration 687 ms
403:04:02.827 probeConfiguration 2459 ms
503:19:02.838 probeConfiguration 8059 ms
6...
706:19:02.988 probeConfiguration 2875 ms
806:39:02.994 probeConfiguration 2959 ms
9
10# ~/.local/share/opencode/log/opencode.log at the 05:19 tick
1105:19:03.137Z cli starting version=2.1.4 args="[\"acp\"]"
1205:19:03.178Z spawning process command=~/.t3/tools/opencode-v2/2.1.4/linux-x86_64/opencode args="[\"serve\",\"--stdio\",\"--port\",\"0\"]"
13
14# session_v2 row created at 05:19:04 (empty)
15title="" agent="" model="" version="2.1.4" msgs=0
16
17# SQL verification against a pre-cleanup copy of ~/.local/share/opencode/opencode.db
18sqlite3 ~/.local/share/opencode/opencode.db <<'SQL'
19SELECT datetime(time_created / 1000, 'unixepoch', 'localtime') AS created,
20 version, title, agent, model
21FROM session_v2 s
22WHERE (title IS NULL OR title = '')
23 AND version = '2.1.4'
24 AND NOT EXISTS (SELECT 1 FROM session_message m WHERE m.session_id = s.id)
25ORDER BY time_created;
26SQL
272026-10-26 03:04:04|2.1.4|||
282026-10-26 03:19:04|2.1.4|||
292026-10-26 03:34:04|2.1.4|||
30...
312026-10-26 06:19:04|2.1.4|||
322026-10-26 06:39:05|2.1.4|||

Screenshots, recordings, or supporting files

No response

Workaround

Settings → Background Activity → Provider health interval = 0 seconds stops the periodic probes (T3 still probes once at startup).

Synced from GitHub

The same probe leak also affects Kiro CLI, set up as a local ACP command (kiro-cli acp --agent-engine=v3, Kiro CLI 2.35.1).

  • On session/new, Kiro persists the session straight away. The wire log shows _kiro/sessions/changed with the new session in upserted before any prompt, and a sess_<id> directory under Kiro's own sessions folder.
  • A runtime.start() that is then closed without session/close or session/delete leaves that session in Kiro's session list. I confirmed this with T3's own AcpSessionRuntime; the leftover directories only disappeared after I deleted them manually.

One caution about the fix proposed here (runtime.deleteSession guarded by sessionCapabilities.delete): for agents that answer initialize in the v1 shape, such as Kiro, deleteSession currently fails locally and sends nothing, so it would not clean up either. That is tracked in #26927.