zed/crates/agent
zed-zippy[bot] 70d55e7016
Fix agent threads missing from sidebar after upgrade (#54723) (cherry-pick to preview) (#54751)
Cherry-pick of #54723 to preview

----
Fixes #54618.

## Summary

After upgrading from `v0.232.x` to `v0.233.5+`, many users reported that
most
of their agent threads "disappeared" from the sidebar. The threads are
still
on disk in the legacy `threads.db` — but they never make it into
`sidebar_threads`, which is the only table the new sidebar UI reads
from, so
they're unreachable from the UI.

The root cause is a race between `ThreadStore::reload` and
`migrate_thread_metadata`:

- `ThreadStore::new` constructs with an empty in-memory `Vec` and kicks
off
  `reload()` as a fire-and-forget task.
- `migrate_thread_metadata` runs during `agent_ui::init` and reads
  `ThreadStore::global(cx).read(cx).entries()` synchronously, without
  awaiting that reload.
- On cold boot the migration observes an empty iterator, early-returns
on
  `to_migrate.is_empty()`, and never populates `sidebar_threads`. The
  migration runs every launch, so it keeps losing the race forever.

Empirically, the only rows that *did* end up in `sidebar_threads` for
affected users came from `handle_conversation_event` writing rows when
the
user actively interacted with a thread. That's why users would typically
see
a handful of recently-touched threads rather than their full history.

## Fix

1. `ThreadStore` now tracks its current reload as a `Shared<Task<()>>`
and
   exposes it via `reload_task()`. `migrate_thread_metadata` awaits this
   before reading `entries()`.
2. Move the top-5-per-project unarchive pass out from under the
   `is_first_migration` guard. Previously the rescue only ran when
   `sidebar_threads` was empty, which meant any user who had even one
pre-existing row (e.g. from interacting with a thread on a prior launch)
got every subsequent batch of migrated threads archived with no rescue.
   Running the rescue per-batch is stateless and idempotent — a user who
bounces between older releases and newer ones still gets their top 5 per
   project surfaced each time a new batch is migrated.

No new KVP flag or one-shot backfill is needed: because the migration
already dedupes by session_id and runs on every launch, the next cold
boot
on a fixed build picks up any legacy threads that earlier launches
missed.

## Structure

The PR is split into two commits to make the diff easy to verify:

1. **Regression test** — fails on `main`, reproduces the cold-boot race
by
seeding the legacy DB, reinitializing `ThreadStore` to get a fresh empty
   cache, and running the migration without parking first.
2. **The fix** — gates entries reads on `reload_task().await`, and
adjusts
the per-batch rescue policy. Updates one existing test's assertions to
   match the new per-batch rescue policy.

## Validation

- The regression test fails on `main`, passes after the fix.
- All `agent_ui`, `agent::thread_store`, and `sidebar` lib tests pass.
- `./script/clippy -p agent -p agent_ui` is clean.
- End-to-end repro with a real on-disk data dir: launched `v0.230.2 →
v0.231.2 → v0.232.3 → v0.233.8` as a non-staff user, creating 15 threads
  and interacting with one, reproduced the reported state (1 thread in
sidebar, 14 missing). Launched a debug build of this branch against the
same data dir: `Migrating 14 thread store entries` in the log, 15 rows
in
`sidebar_threads` with 6 unarchived (the interacted-with thread plus the
  5 most recent), 9 archived and reachable from the archive view.

Release Notes:

- Fixed agent threads appearing to be missing after upgrading to the
parallel-agents sidebar. The thread-metadata migration was racing
against the on-disk thread store's async reload and skipping itself on
every launch. Upgrading to this build runs the migration successfully;
previously-missing threads are surfaced either in the sidebar (5 most
recent per project) or in the archive view.

Co-authored-by: Eric Holk <eric@zed.dev>
2026-04-24 08:42:36 +00:00
..
src Fix agent threads missing from sidebar after upgrade (#54723) (cherry-pick to preview) (#54751) 2026-04-24 08:42:36 +00:00
Cargo.toml eval: Remove deprecated eval crate and workflow (#52733) 2026-03-30 13:33:29 +00:00
LICENSE-GPL Rename assistant2 to agent (#27887) 2025-04-02 00:40:47 +00:00