Skip to content

[Bug]: New thread in a freshly-created project gets stuck on "Loading messages..." forever, even though the backend completes the turn #11681

Description

@codeclawd

Title: [Bug]: New thread in a freshly-created project gets stuck on "Loading messages..." forever, even though the backend completes the turn

Area: apps/desktop

Steps to reproduce:

  1. Point T3 Code at a project folder whose path recently changed on disk (e.g. moved from ~/Desktop/Projects/foo to ~/Projects/foo), such that the old sidebar entry no longer resolves cleanly.
  2. Open/select that project and send the very first message in a brand-new thread.
  3. Observe: T3 silently creates a second, duplicate project record for the same folder (confirmed via ~/.t3/userdata/state.sqlite, projection_projects — two rows with the same title and different workspace_root casing/path, one created seconds before the new thread).
  4. The new thread's turn actually completes successfully server-side within ~10 seconds (all orchestration_events for the thread — thread.created → thread.message-sent → thread.turn-start-requested → several thread.session-set → thread.message-sent (assistant) → thread.activity-appended → final thread.session-set (status ready) → thread.meta-updated — fire and complete cleanly, no errors).
  5. Despite this, the composer UI stays on "Loading messages..." indefinitely. The main content pane never renders anything (not even the two messages that exist in projection_thread_messages).

Expected behavior: The thread should render the completed turn's messages and clear the loading state, exactly as it does in every other (non-brand-new) project's threads.

Actual behavior: The composer shows "Loading messages..." forever. Typing and clicking send is a silent no-op (text stays in the box, no new turn starts, sidebar timestamp never updates). Switching to model Sonnet+Low, navigating away to a different thread and back, and reloading did not clear it. state.sqlite shows the turn is state=completed, the thread session status=ready, last_error is null, and both the user and assistant messages exist in full with is_streaming=0. So this is purely a client-side rendering/subscription bug, not a backend failure — my best guess is a race where the renderer's live-event subscription for the thread attaches after the whole event burst (all 16 events within ~12s) has already fired, so it's left waiting on a "loaded" signal that already happened and never arrives again.

Impact: Blocks work completely (on that one thread — have to abandon it and start a new thread, which works fine).

Version: 0.0.40 (macOS, Alpha)

Environment: macOS 25.5.0 (Darwin), T3 Code (Alpha) 0.0.40

Workaround: None found that recovers the stuck thread (tried: switching model, switching threads and back, retyping and resending). Only workaround is to delete/archive the stuck thread and start a new one in the same project, which loads normally.

Secondary bug also observed: T3 silently created a duplicate project entry for the same on-disk folder (reachable via two path spellings due to a symlink, ~/Desktop/Projects/foo -> ~/Projects/foo) instead of resolving to the existing project record. This orphaned the new thread in a project with zero prior history, likely contributing to the race above (a project with no established event history has its very first thread hit the full burst-of-events-before-subscription race described above).

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions