Agents view: Ctrl-X unbinds a session — sending to that row creates a job that never binds and never runs

Status Closed — not planned
Reported on v2.1.251
Maintainer reply None cached
Activity 2 comments · opened Sep 3, 2026 · closed Sep 10, 2026
Provenance: investigated and drafted by Claude Code (Opus 5) running on my machine against my own ~/.claude state, then independently re-verified by a second Claude Code agent given only this text and read-only access. I have read it in full and I am filing it deliberately. Machine-generated, human-reviewed, human-endorsed.
Redaction: one client reference is masked as <redacted> in a session name; its shape is preserved because the name is part of the symptom. Nothing else is altered. Timings, byte counts, session UUIDs and job-record field values are verbatim and were each checked against the artifacts on disk.

What's Wrong?

Pressing <kbd>Ctrl</kbd>+<kbd>X</kbd> on a row in claude agents removes the job record at
~/.claude/jobs/<short>/ but leaves the session transcript at
~/.claude/projects/<slug>/<sessionId>.jsonl intact.

Sending a message to that session afterwards does not resume it. A new job with a new
session id
is created, it never binds to the existing transcript, and — in both cases I
have on disk — it never ran at all: no transcript of its own was ever written, and unlike
every other job on this machine it produced no timeline.jsonl. The message goes nowhere.

The agent I did reach replied with no knowledge of the conversation. The original session
was still perfectly intact and claude --resume <sessionId> reached it immediately.

What Should Happen?

  1. Ctrl-X should archive a row, not unbind the session behind it. Clearing finished agents

off the board is ordinary tidying; a board you cannot tidy is not a board.

  1. Sending to a session the view is willing to display should resume that session, or fail

loudly. It should not silently create a different, empty session and accept the message
into it.

Evidence

Original session 686e30ee-1a1f-4ff3-9804-abf4d04a56c3, name <redacted>-vm-setup:

  • transcript intact — 2,875,269 bytes, 1485 lines, last message 2026-09-03T02:30:19.546Z;
  • daemon.log line 6 is [2026-09-01T22:26:02.348Z] [bg] bg spawned 686e30ee (slash), so

it did once have a job record;

  • ~/.claude/jobs/686e30ee/ does not exist.

The two jobs created by sending to that row afterwards:

| field | 01eb53de | e31e0dfd | every other job on this machine |
|---|---|---|---|
| sessionId | 01eb53de-7a53-… (its own) | e31e0dfd-6aa1-… (its own) | — |
| resumeSessionId | its own id | its own id | its own id |
| nameSource | collision | collision | auto / user |
| cliVersion | absent | absent | 2.1.251 |
| linkScanPath | absent | absent | present |
| linkScanOffset | 0 | 0 | non-zero |
| output | null | null | populated |
| timeline.jsonl | absent | absent | present (10/10) |
| transcript on disk | none | none | present |
| createdAt → reapedMidWorkAt | +241 ms | +998 ms | n/a |

The missing timeline.jsonl is the sharpest signal: all ten other job directories have one,
these two have only a state.json. Nothing ever ran.

The dispatcher could read the old transcript but did not bind to it. Both jobs have
fields copied verbatim out of 686e30ee's transcript:

  • e31e0dfd.intent is an exact 200-character prefix of the 237-character user prompt

recorded in 686e30ee at 2026-09-03T02:24:28.412Z — byte-identical, just truncated;

  • e31e0dfd.detail is a whitespace-normalised, truncated copy of the assistant message in

686e30ee at 2026-09-03T02:27:16.081Z (the transcript's :\n\n** appears in detail
as : **).

So the code path that created the job had the transcript in hand and still assigned a fresh
session id. That inconsistency is, I think, the most useful thing in this report.

Explicitly NOT claimed

I want to head off two things a reasonable reader would suspect, because I checked both and
they do not hold:

  • No data was lost. An earlier draft of this report claimed an hour of untracked work

had vanished. That was a timezone error on my part — ls prints local time (BST), job
records are UTC. Everything is present in 686e30ee's transcript. This is a bookkeeping
and routing bug, not a data-loss bug.

  • The (2) / (3) suffixes are not mysterious. A live job 36cb21fd, state done,

still listed in claude agents --json, holds the base name <redacted>-vm-setup. That
fully explains the collision counter. I am not claiming the name was resurrected from the
orphaned transcript.

Steps to Reproduce

I can describe the state precisely but not yet reduce it to a deterministic script — the two
occurrences on this machine both involved a (slash)-spawned job with
interactiveLineage: true, and I do not know whether that is load-bearing.

  1. From an interactive session, dispatch a background agent so a job appears in

claude agents (mine had template: "bg", interactiveLineage: true).

  1. Let it build a transcript, then note its session id from

~/.claude/jobs/<short>/state.json.

  1. Press <kbd>Ctrl</kbd>+<kbd>X</kbd> on its row. Confirm ~/.claude/jobs/<short>/ is gone

and ~/.claude/projects/<slug>/<sessionId>.jsonl remains.

  1. Send a message to the session from the agents view.
  2. Expected: the session resumes. Observed here: a new job directory appears with a

different sessionId, nameSource: "collision", no cliVersion, no linkScanPath, no
timeline.jsonl, and no transcript is ever written for it.

claude --resume <original-session-id> continues to work throughout, which is what
establishes that the transcript was only unbound and not damaged.

Impact

The message you send is silently discarded, the board accumulates numbered dead rows, and
the only way back into the session is claude --resume with an id the UI does not display.
For a view whose purpose is managing sessions without dropping to the CLI, that is the whole
value proposition failing quietly.

Notes for triage

The two job records above no longer exist in my live store — I cleaned them up before
understanding they were evidence. I have preserved a complete snapshot of all twelve job
records plus the full daemon.log, and can attach them on request.

Related

  • #91769 — background-agent adoption never succeeds; live sessions marked Failed. Filed

alongside this one. The two junk jobs described above also carry reapedMidWorkAt, so the
reports overlap on those records, but the bugs are independent: this one is about the
session never being bound, that one about how the daemon reports workers after a restart.

Claude Code Version

2.1.251

Platform

Claude subscription, CLI

Operating System

Linux (CachyOS, kernel 7.2.2)

Terminal/Shell

kitty / zsh

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗