[Bug]: Ghost topic persists after deletion — "cannot open session", not openable, not deletable

Author: leonardoalcantaraCreated Sep 16, 2026Updated Sep 17, 2026
Labelsbugdesktopv2macos

Version line

v2 — Go rewrite (1.x), main-v2 (active development)

Exact version

1.38.7 (stable) — also reproduced on 1.38.6

What happened?

A topic appears in the project tree, but clicking it fails with "cannot open session". It cannot be opened and cannot be deleted through the UI.

The topic does not exist in any authoritative on-disk state. It survives:

  • Cmd+Q and full relaunch (multiple times)
  • kill -9 of all Electron helpers (user-data-dir=~/.reasonix/desktop-shell), then relaunch
  • deletion of ~/.reasonix/desktop-shell/Local Storage/leveldb (recreated on next start)
  • upgrading 1.38.6 → 1.38.7
  • removing the project from the app and re-adding it from the directory

The last point is the most telling: the ghost is re-attached to the same project path after the project is recreated from scratch, which suggests it is keyed by project path in a cache that is not cleared when the project is removed.

Steps to reproduce

  1. Have a project at path /Users/leo/dev/faxina with a conversation (topic topic_20260911-125005_0ae5c72ee57deb11).
  2. Rename the project directory to /Users/leo/dev/marypoppins.
  3. The session stays orphaned under the old project root; the app switches to the new root and creates a fresh session there.
  4. A symlink ~/dev/faxina~/dev/marypoppins was created afterwards to keep the old path working. The symlink did not recover the orphaned session — by then the app had already moved to the new project path.
  5. Delete the old conversation. The files move to sessions/.trash/, the topic is added to deletedTopics. The topic nevertheless remains listed and becomes permanently stuck.

Before deletion, that session's turns.jsonl recorded:

"lastStatus": "recovery_required"

on 8 of 10 turns — accumulated from repeated interrupted turns (<interrupted-turn-recovery> messages were present in the transcript). This may relate to the diverged_recovery handling in #8425 and the ghost-row fallback in commit 0cc808a.

Verification: the topic is NOT in any active state

Checked directly on disk, with the app closed:

Location Contains topic_...125005...?
desktop-projects.jsonprojects[].topics no
desktop-projects.jsondeletedTopics yes (correct place for a deleted topic)
desktop-project-tree-organization.jsontopicOrder no
projects/-Users-leo-dev-marypoppins/desktop/topic-state-v1.sqlitetopics no (table holds only the one live topic)
projects/-Users-leo-dev-marypoppins/sessions/ no
desktop-tabs.json no
desktop-shell/Local Storage/leveldb no after rm -rf + dead process

All six locations are clean, yet the UI still renders the row.

Suspected area

projectTree:readActivity in Local Storage/leveldb stores a map of project \x1f <project-path> \x1f <topic-id> → last-read timestamp, plus a projectTree:readActivityBaselineAt key. The ghost reappears in that map after being removed.

Because the key includes the project path, deleting and re-adding the project at the same path appears to re-hydrate the ghost from this cache.

Questions

  1. Is there an additional persistence layer for project-tree topics beyond the locations listed above?
  2. Is there a supported way to drop a single topic from the project tree (CLI flag, repair command, or safe surgery on state) when the UI can neither open nor delete it?
  3. Does the project-tree fallback in commit 0cc808a (ordinaryTreeHidesUnindexedBlank, projectTreeWithoutTopic) cover a topic that is present in deletedTopics and in the readActivity cache but absent from every authoritative index?

OS / platform

macOS 26.6.2 (build 25G83), Apple Silicon (arm64)

Relevant logs or output

bash

Source: esengine/DeepSeek-Reasonix