Skip to content

bug(dispatch): prompt to a hibernated agent in a Grid Dispatch lane is rejected as not a live agent session #690

Closed

Description

@Juliusolsson05

Expected

Typing a prompt into an agent shown in a Grid Dispatch lane delivers it. If that agent is hibernated (detached, restored from workspace.json without a provider process), it is woken under the same SessionId first.

Actual

Delivery is refused:

Cannot deliver prompt: <id> is not a live agent session

Reproduced from the live lifecycle journal, app run 2026-08-30T20-05-09-879Z-main-57466-902f71:

20:07:20.238  delivery.reject  sessionId c0f448e4-…
              code=not-ready  stage=before-write
              registryHit=false  reason="never-owned"

c0f448e4-… is present in the persisted workspace under both sessions and detachedSessions — a hibernated detached agent. reason: "never-owned" is sessionManager's own discriminator for "main has never held this id this run", which is exactly what a hibernated session looks like.

The row in question is project-bound:

"rows": [{ "length": 5, "capChildren": true, "projectTabId": "7e853279-…", "height": 0.548… }]

Root cause

rehydrate.ts:325 deliberately does not respawn detached sessions: "Detached (hibernated) sessions are intentionally not respawned during rehydrate". Something must therefore wake them before they are used.

Exactly one path does. hook/actions/agentIndexNavigation.ts:47 calls ensureSessionLive and says why:

"Detached agents survive reload as metadata without a provider process. Wake under the SAME SessionId before exposing one in a lane/grid slot; otherwise the navigation appears to work but the first keystroke lands on a dead backend."

That is a precise description of this bug. But the four paths that actually put a session into a lane all write straight through setTiledLaneSession with no wake:

Path File
Row index list click TiledDispatchLayout.tsx → focusSessionInTab
Lane strip click TiledDispatchLayout.tsx → DispatchMiniList onSelect
⌥↑ / ⌥↓ useKeybinds.ts moveTiledLaneSelection
⌘N useKeybinds.ts focusTiledRowByIndex

Is this new?

The gap is pre-existing — setTiledLaneSession has never woken, including in single-row Tiled Dispatch before #687 (git show 18160020^1 shows the same non-waking focusSessionInTab).

#687 made it far more reachable, and both halves matter:

  • Binding a row to a project promotes Dispatch scope to global, which surfaces other projects' detached agents in that row's index — the ones most likely to be hibernated after a restart.
  • Removing auto-fill means every lane is now filled by a deliberate user pick through one of the four non-waking paths.

Impact

User-visible failure on a normal action, with a pane left showing Sending until the agent is reloaded. The composer's own retry (TileLeaf.tsx:302-314) calls ensureSessionLive, which is why this is intermittent rather than total, but it is not reliable and the user sees the error.

Fix direction

Lane selection should wake, the same way agent-index navigation does — one action that awaits ensureSessionLive for a detached target before writing the lane, with all four call sites routed through it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions