Skip to content

web-runtime-wake-terminal-respawn latch is keyed by worktree alone and cleared across environments #19898

Closed

Description

@nwparker

What

src/renderer/src/runtime/web-runtime-wake-terminal-respawn.ts keys its in-flight latch by worktree id alone, and clearWebSessionTabsTrackingForEnvironment releases every environment's keys via clearAllWebRuntimeWakeTerminalRespawn().

const wakeTerminalRespawnInFlightByWorktree = new Set<string>()

A worktree id is repoId::path and carries no host component, so the same id can be live on two paired runtimes at once (STA-4343). That makes both halves wrong in the same way:

  • one environment's teardown releases a sibling environment's in-flight respawn, so a new subscription for that sibling can create a duplicate terminal;
  • one environment's in-flight respawn blocks a sibling environment's legitimate one.

Why this is filed rather than fixed

This is the exact defect #18513 fixed for the sibling initial-terminal bootstrap latch, which is now keyed (environmentId, worktreeId) with a per-environment teardown that clears only its own keys.

The wake-respawn latch was deliberately left out of that PR because it is not reachable from the emptied-workspace repro: shouldRespawnWebRuntimeTerminalAfterWake returns false when localTerminalCount === 0 (tracking-decisions.ts), so an emptied workspace never reaches this latch through the stream-frame path. Re-verified on the current branch. Widening #18513 to cover it would have mixed an unreachable hazard into a data-loss fix.

It is still reachable through its own path — a workspace with tabs whose PTYs died, on two paired runtimes sharing a worktree id.

Fix shape

Mirror web-runtime-initial-terminal-bootstrap.ts exactly: key by (environmentId, worktreeId), and make the environment teardown in tracking-lifecycle.ts clear only that environment's keys instead of calling clearAllWebRuntimeWakeTerminalRespawn().

Note ensureWebRuntimeWorktreeTerminalAfterWake (src/renderer/src/lib/web-runtime-worktree-terminal-after-wake.ts) is a second consumer of the same latch and resolves its own runtimeEnvironmentId, so it can pass one through without new plumbing.

Activity

  1. nwparker commented on Sep 10, 2026

    @nwparker
    ContributorAuthor

    Closing — this was filed by an automated review pass that should not have opened GitHub issues. The finding is real and is retained in our internal report; it is not lost by closing here.

    No action needed from anyone. Reopen if you want it tracked publicly.

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

Metadata

Metadata

Assignees

No one assigned

    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