[BUG] Sessions containing /loop command are permanently hidden from /resume
If a session contains even a single /loop invocation (regardless of whether it was the session's primary purpose), that session is permanently filtered out of the /resume picker — including search.
Steps to reproduce
- Start a normal session
- Run
/looponce (e.g. to try it out), then stop it - Continue working in the same session as usual
- Exit and try to find the session via
/resume— it's gone
Expected behavior
Sessions should only be hidden from /resume if they were exclusively loop sessions (no human conversation after the loop ended), or not hidden at all — with a visual indicator instead.
Actual behavior
The session is permanently excluded from /resume and from search. The only workaround is claude -r <session-id> with a manually copied UUID.
Root cause (found via binary inspection)
The filter checks r.includes("<command-name>/loop</command-name>") on the raw session file content and marks it as filtered from /resume: /loop session. One match = excluded forever, regardless of what happened in the session after.
Version
2.1.201
3 Comments
Independently reproduced on 2.1.204, and the substring root cause is even more damaging than the report states: the filter fires on the literal string appearing anywhere in the raw file, so a session where
/loopwas never invoked still gets permanently hidden — as long as the tag string<command-name>/loop</command-name>shows up in any tool output or pasted text.False-positive amplification (zero-invocation sessions get hidden)
The check is a raw
content.includes("<command-name>/loop</command-name>"), not a structural test against actual command entries. So the string leaks in through totally normal activity:grep/cat/Readof session.jsonlfiles,history.jsonl, or another transcript that quotes a/loopline → the tag string lands in atool_resultand poisons the current session.The session is then filtered from
/resumeforever, despite never running/loop.Concrete self-referential instance
On my machine, across 29 sessions in one project, exactly one session had a genuine user-typed
/loop. But three sessions contain the tag string in raw content:| Session | genuine
/loopinvocations | raw occurrences of the tag string | source of the string ||---|---|---|---|
|
6807f3e0…| 1 | 1 | actual/loopcommand ||
e0233c01…| 0 | 2 | inside atool_result— agrepof session history that quoted another session's/loop||
eb5fc1cf…(current) | 0 | 5 | my owngrepcommands while investigating this very issue |e0233c01is a high-value spec-writing session I lost and spent a long time hunting for — it vanished from/resumepurely because an earlier in-sessiongrepembedded the tag string into its transcript. And the act of investigating this bug (grepping for/loop) embedded the string into the current session, which means the investigation session will now be hidden too. The filter is effectively self-propagating.Fix direction
The check must be structural, not a substring scan. Only count an entry as a
/loopinvocation when it is an actual command record — e.g. atype: "user"/local_commandentry whosemessage.contentis a string that starts with the/loopcommand tag — and explicitly excludetool_resultpayloads (array-type content) and pasted text. A session that merely mentions the string in tool output or a paste must not be filtered.(Separately worth deciding, per the report's "Expected behavior": even a genuinely loop-invoking session probably shouldn't be hidden outright — a
bg/loop indicator in the picker would be enough, so the conversation stays reachable.)Environment
Updated
Confirming on Linux (WSL2), 2.1.205 (sessions recorded on 2.1.204) — both reports above are macOS, so this isn't platform-specific.
Genuine-invocation case reproduces: across 45 substantial sessions in one project, the correlation is exact — every session containing an actual
/loopcommand is gone from/resume(and its search); every session without one appears. My three hidden sessions all used/loopto drive an unattended workflow, e.g./loop /run-phase <section>. Recovered fine viaclaude --resume <uuid>, consistent with #73089 noting the CLI path is unaffected.Could not reproduce the raw-substring false positive on 2.1.205 — possible fix between 2.1.204 and 2.1.205. A session that contains
<command-name>/loop</command-name>only inside tool output (e.g. fromgrep-ing other transcripts), but never ran/loopas a command, appears normally in/resume. In my case that session held the tag string 34× purely from investigation greps and was not hidden — verified by fully closing it (/exit) and reopening it from the picker (so it's not a current-session artifact), and it stayed visible after a/renametoo. That's the opposite of the comment above (whose leaked-string sessions were also un-renamed), so on 2.1.205 the filter looks structural (real command record) rather than a whole-filecontent.includes(...). Worth confirming the false positive was fixed in this window.+1 on the fix direction either way: match only actual command records, exclude
tool_result/ pasted content, and per the original "expected behavior" prefer a bg/loop indicator over hiding a session that had normal conversation after the loop ended.This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.