Skip to content

Terminals are killed when their location is evicted after 60 minutes of chat inactivity #48691

Open

Description

@iyernaveenr

Description

Terminals opened in the desktop app die after about an hour without chat activity in that project. The pane goes blank and the scrollback is gone; the server log shows the location being torn down and rebuilt, followed by fresh "creating session" entries as the app recreates terminals.

Location eviction does not know about terminals. On v2, LocationActivity renews a location only on durable session events, so a running terminal never counts; on dev the LayerMap idle TTL is renewed only by PTY API calls, so an open terminal does not count either. In both cases the eviction runs the Pty finalizer, which kills every running terminal in that location.

I have a fix for v2 with a regression test (a location owning a running terminal is retained past its deadline and evicted once the terminal is gone): https://github.com/iyernaveenr/opencode/tree/naveen_r_iyer/v2-pty-eviction. Happy to open the PR against v2.

Plugins

none

OpenCode version

dev build from source (observed daily on dev bbe4c95; v2 7c5a4d0 confirmed by the test)

Steps to reproduce

  1. Desktop app, open a project, open a terminal in a session and run something.
  2. Send no chat message in that project for 60+ minutes (typing in the terminal does not help).
  3. Come back: the pane is blank, reconnect gets "session not found", and the log shows "location services evicted" (v2) or a fresh "booting location services" (dev).

Screenshot and/or share link

No response

Operating System

Ubuntu 24.04

Terminal

built-in terminal of the desktop app

Activity

  1. ShinjuSakamura commented on Sep 23, 2026

    @ShinjuSakamura

    I agree with this report. The same 60-minute location eviction also stops processes started by the shell tool, not only desktop terminals.

    On v2.0.12 and v2.0.14, LocationActivity resets its deadline only on durable session events. A shell that is still computing, including one started with background: true, does not count. When the location is evicted, that shell is interrupted and its process is cleaned up. I hit this with a multi-hour compute job: the session was already idle, the command was still running, and the process was gone about 61 minutes later, at the same time the server logged "location services evicted".

    layer() already accepts timeToLive, but the service is constructed with the hardcoded "60 minutes" default. There is no opencode.json setting, environment variable, or CLI flag for it.

    Please expose this to users:

    • a configurable idle timeout
    • an explicit option not to kill running processes, either by skipping eviction while a shell or terminal is still running, or by allowing the sweep to be disabled
  2. SamSpiri commented on Oct 3, 2026

    @SamSpiri

    Same TTL eviction, different victim — a background shell job's completion notification, not the terminal.

    Repro on v2.0.22: background: true shell job started in a location; the session ended its turn 30s later (no durable activity after). 60 min later the location was evicted; 8 min after that the job actually completed — but the completion watcher (ShellTool.notifyWhenDone) is forked into the location scope, so eviction interrupted it and sessions.synthetic(...) never fired. No synthetic row exists in the DB for that shellID; the session stayed idle 70 min until woken manually. The shell .out was also deleted, consistent with the watcher's Effect.onInterrupt(() => shell.remove(...)) (tool/plugin/shell.ts:234).

    This is evidence the eviction's blast radius includes location-scoped plugin fibers generally, not only PTYs. If #48730 lands (keeping locations with running terminals out of eviction), the same retention predicate should also count backgrounded shell jobs — otherwise this case survives. PR #52580 targets that specifically.

  3. AlexeyShirshov commented on Oct 14, 2026

    @AlexeyShirshov

    Cross-link: #55305 asks for the 60-minute location TTL to be configurable (or opt-out) — the same LocationActivity deadline that evicts a location owning live terminals here.

    Same root cause, different symptom surfaces, so worth evaluating together: #51828 (background shells SIGTERM'd at the TTL), #51343 (running session / pending question interrupted), #52908 and #54404 (closed). #55305 is the "make the deadline adjustable" lever, not another exemption report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions