Skip to content

[Bug]: New sidebar silently stuck on a remote 'No project' scope, so all projects and Working threads appear missing #16692

Description

@RoySalisbury

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/web

Steps to reproduce

  1. Use the desktop app with several connected environments (local plus a few remote servers).
  2. At some point the sidebar project scope gets set to a remote environment's No project (scratch) project. I'm not sure how it happened. It may have been an accidental click in the project-scope picker (the dashed-square icon next to Search), or it may have come from the v1 → v2 localStorage import (v1-local-storage-imported is dated around when this started).
  3. Use the new (non-legacy) sidebar.

Expected behavior

The sidebar shows all projects plus the Working and Settled shelves across every environment. If a project scope is active, it should be obvious in the sidebar and easy to clear.

Actual behavior

The new sidebar showed no projects and an empty Working shelf, even with active threads on the local machine and on two remote environments. Settled showed only two old threads, which turned out to be the settled threads in that one remote scratch project. Nothing in the sidebar indicated it was filtered. It looked like the app had lost all of its threads.

  • Turning on the legacy sidebar showed everything, because it ignores the scope.
  • Other machines connected to the same environments were fine, because the scope is stored per client.
  • This lasted for several days across nightly updates.
  • I couldn't clear it from the sidebar UI. Switching back from the legacy sidebar still showed the empty view.

The stuck value, in localStorage t3code:ui-state:v1:

"sidebarProjectScopeKey": "<remote-env-id>:/home/<user>/.t3/scratch"

Setting sidebarProjectScopeKey to null and reloading restored the sidebar right away.

Server and sync were healthy throughout. Shell snapshots loaded from every connected environment, and nothing in the traces indicated a sync problem.

Impact

Major degradation or frequent failure

Version or commit

0.0.46-nightly.20261006.2752 (also present on 0.0.46-nightly.20261003.2632)

Environment

macOS 27.0 (Apple Silicon), T3 Code (Nightly) desktop app; remote environments on Linux running 0.0.46-nightly.20261006.2735

Logs or stack traces

# No errors. The only relevant state was the persisted scope:
# localStorage["t3code:ui-state:v1"].sidebarProjectScopeKey = "<remote-env-id>:/home/<user>/.t3/scratch"

Workaround

Open DevTools (⌥⌘I) and run:

const k = 't3code:ui-state:v1';
const s = JSON.parse(localStorage.getItem(k));
s.sidebarProjectScopeKey = null;
localStorage.setItem(k, JSON.stringify(s));
location.reload();

Turning on the legacy sidebar also works around it.

Suggested fixes:

  • Show a visible "Scoped to · Clear" indicator when a scope is active.
  • Validate or reset a scope that points to a scratch project or one that isn't visible.
  • Give the user a clear way to reset it.

🤖 Generated with Claude Code

Activity

  1. juliusmarminge commented on Oct 7, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Confirmed on main (bfec2387b): a persisted sidebarProjectScopeKey pointing at a remote scratch project can silently filter the new sidebar down to that one “No project” catalog entry, with no strong clear affordance.

    Mechanism (matches the report)

    • Scope is stored per client in localStorage key t3code:ui-state:v1 as sidebarProjectScopeKey (uiStateStore.ts, L30, L157). Load/set only sanitize “non-empty string or null” — no scratch / visibility check (setSidebarProjectScopeKey).
    • Physical/logical keys for non-git projects are ${environmentId}:${normalizedWorkspaceRoot} (derivePhysicalProjectKeyFromPath), which matches the stuck value "<remote-env-id>:/home/<user>/.t3/scratch".
    • Scratch is a real catalog project titled No project, with a dashed chat-bubble icon at create (ManagedProjectFolders.ts, L317-L324). It is included in projectGroups / the scope combobox (unlike the command palette, which strips scratch from normal project rows).
    • While scoped, filterSidebarV2VisibleThreads keeps only threads whose environmentId:projectId is in that group (Sidebar.logic.ts). Working empties; Settled can still show that scratch project’s settled threads — exactly the “everything missing except a couple of Settled rows” shape.
    • Auto-reset only runs when the scoped group is missing from the catalog after snapshots are ready (Sidebar.tsx). A live scratch project never trips that path, so the filter sticks across reloads/nightlies.
    • Active-scope UI is only the header icon swapping to the project favicon (aria-label Filter threads by project: …) (Sidebar.tsx). There is no “Scoped to … · Clear” chip. For scratch, that favicon is the dashed bubble, so it is easy to miss next to Search.
    • Legacy sidebar reads other UI-store prefs but not sidebarProjectScopeKey, so it shows everything; other clients are unaffected because the key is local.

    How the key gets set (picker or thread context “filter by project”) is plausible; v1→v2 localStorage import could also carry an existing t3code:ui-state:v1 value. We did not need to pin the exact entry path — once set, persistence + missing clear UI are enough to explain days of breakage.

    Related (different)

    • #14260 — similar “only Settled visible” symptom; closed needs more info around DB/render, not project scope.
    • #12113 — open UX PR to distinguish the unscoped filter icon from “new project”; does not validate/reset scratch scopes or add a clear chip.
    • #14165 / #14997 — scoped new-chat and environment filter features; not this stuck-filter bug.
    • Merged #9416 — moved the filter into persisted UI state (why a bad key survives Settings/restarts). No open PR found that fixes silent scratch scope.

    Workaround (as reported) — null sidebarProjectScopeKey and reload, or use the legacy sidebar. Opening the scope combobox and choosing All projects should also clear it when the picker is reachable.

    Next step

    Treat as a product bug in the new sidebar scope control:

    1. Show an obvious active-scope indicator (e.g. “Scoped to No project · Clear”) whenever sidebarProjectScopeKey !== null, not only an icon swap.
    2. On load / when snapshots are ready, validate the key: if it resolves to a scratch project (isScratchProject / scratchWorkspaceRoot) or to a group the user cannot reasonably discover, reset to null (or at least refuse to keep scratch as a sticky scope).
    3. Optionally keep scratch out of the scope combobox the same way the command palette keeps it off the normal project list, while still allowing an explicit temporary filter with a clear exit.

    Thanks for the localStorage dump and the legacy-vs-new comparison — that made the root cause easy to confirm on main.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 7, 2026
  3. added a commit that references this issue on Oct 8, 2026
  4. paulomoguerra commented on Oct 8, 2026

    @paulomoguerra

    Same root cause here, but the stuck scope was a regular local project, not a scratch one.

    • 0.0.46-nightly.20261008.2819, macOS 27, Apple Silicon.
    • New sidebar: no projects, empty Working shelf, only "Settled (22)". The server was healthy: t3_thread_list returned active threads in every project.
    • The only sign of the filter was a two-letter badge ("CK", the project's initials) next to Search, in place of the filter icon. I didn't recognize it as an active filter and don't know how it got set.
    • The scoped project had no active threads, so the sidebar looked like everything was gone.
    • Sidebar (legacy) showed everything. Turning legacy off, opening the badge and choosing All projects fixed it (Settled went from 22 to 246).

    So point 2 (resetting scratch scopes) wouldn't cover this case: any scope on a project with no active threads looks like data loss. The visible "Scoped to · Clear" chip from point 1 would have caught it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions