pingdotgg / pingdotgg/t3code

[Bug]: Regenerate title never updates the UI — thread stays stuck on the old title while the server commits the rename

Open
#7,328 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

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. Open any thread that already has a generated title.
  2. Right-click the thread in the sidebar (or use the thread's menu) → Regenerate title.
  3. Watch the thread title and the context menu afterwards.

Text generation provider is healthy throughout (cursor / grok-4.5, probe status: "ready"); automatic first-turn title generation works on the same setup.

Expected behavior

The title updates in place once the server finishes the regeneration, and the pending state clears.

Actual behavior

The UI never reflects the result. The thread keeps showing the previous title in the dimmed "regenerating" style, and from then on the menu entry is permanently Regenerating… / disabled. I have never once seen this action visibly change a title, across several versions and on Linux, macOS and Windows.

The confusing part: the server side actually works. The regeneration completes and the new title is persisted — the client simply never applies it.

Evidence from my local event store (~/.t3/userdata/state.sqlite):

  • 4 client-issued thread.meta-updated events with regenerateTitle: true.
  • Each one is answered 7–19 s later by a server thread.meta-updated carrying a new title and titleRegeneration: null.
  • projection_threads holds those new titles today, and no row has a non-null title_regeneration_request_id.
request server completion delay
2026-08-10T08:13:44Z, previousTitle "Changelog t3code 0.32 nightly" title "T3 Code Nightly Changelog Tracking", titleRegeneration: null 7 s
2026-08-10T09:41:57Z new title written, titleRegeneration: null 15 s
2026-08-10T13:50:22Z new title written, titleRegeneration: null 9 s
2026-08-12T08:44:10Z new title written, titleRegeneration: null 19 s

(three titles redacted — client project names)

So the completing event exists, is persisted, and clears titleRegeneration — but the client keeps its pending flag.

Second-order effect, which is what makes it look completely dead: once that flag is stuck, further clicks send nothing at all. I clicked Regenerate title while tailing the logs; the websocket was live (ws.rpc.server.reportClientActivity a few seconds earlier), yet there was no orchestration.command.thread.meta.update span and no new event in the store. That matches the client handler in the shipped bundle:

case `regenerate-title`: { if (m) return; let t = await x({... regenerateTitle:!0}); ... }
// m = a.titleRegeneration != null

a bare return with no toast, no logging, no recovery — and the menu is built with label: e.isRegeneratingTitle ? "Regenerating…" : "Regenerate title", disabled: e.isRegeneratingTitle. There is no timeout or reconciliation against the server projection either, so the action stays inert for that thread indefinitely.

Not the same as #5359: there, text generation itself fails because the provider is unhealthy. Here generation succeeds and the rename is committed server-side; the defect is that the client never consumes the completion.

Impact

Major degradation or frequent failure

Version or commit

Nightly channel, currently 0.0.34-nightly. Unchanged across 0.0.32 → 0.0.33 → 0.0.34; I have never seen this action work on any version.

The traces and the bundle snippet below were captured against server runtime 0.0.33-nightly.20260810.1056 (the runtime process still active during the capture, while the desktop shell was already on the 0.0.34 nightly line) — so the client/server pair in this capture was drifted, but the behaviour is identical on a matched pair.

Environment

Linux (Arch, Hyprland), desktop AppImage on the nightly channel (0.0.34-nightly); also reproduced on the macOS and Windows desktop builds. Providers: claudeAgent (Claude Max, ready), cursor (ready). textGenerationModelSelection: { instanceId: "cursor", model: "grok-4.5" }.

Logs or stack traces
# Regeneration requests (client) — event store
sqlite3 state.sqlite "select occurred_at, substr(payload_json,1,120) from orchestration_events
  where payload_json like '%\"regenerateTitle\":true%' and actor_kind='client' order by sequence desc;"

2026-08-12T08:44:10.759Z|{"threadId":"f0e66a62-...","regenerateTitle":true,"previousTitle":"<redacted>","titleRegeneration":{"requestId":"5c668f0b-f003-49de-be7b-ef9d6a8ab25d",...
2026-08-10T13:50:22.032Z|{"threadId":"c3382cba-...","regenerateTitle":true,"previousTitle":"<redacted>",...
2026-08-10T09:41:57.139Z|{"threadId":"a54c8a65-...","regenerateTitle":true,"previousTitle":"<redacted>",...
2026-08-10T08:13:44.151Z|{"threadId":"fc00ee8c-...","regenerateTitle":true,"previousTitle":"Changelog t3code 0.32 nightly",...

# Matching server completion for the last one — the rename IS committed
2026-08-10T08:13:51.135Z|server|thread.meta-updated|
  {"threadId":"fc00ee8c-...","title":"T3 Code Nightly Changelog Tracking","titleRegeneration":null,...}

# No thread is left pending server-side
sqlite3 state.sqlite "select count(*) from projection_threads where title_regeneration_request_id is not null;"
0

# A fresh click produces no command at all (server trace, click at ~15:15Z)
grep '"orchestration.command.thread.meta.update"' server.trace.ndjson   # last hit 15:05:56Z, unrelated branch update
grep 'regenerateThreadTitle\|processThreadTitleRegenerationSafely' server.trace.ndjson   # no hits
Workaround

None found for the stuck menu entry. The rename is not lost — it is committed server-side, so the new title exists in the projection and should surface on a client reload.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the client regenerate-title handler and the thread context-menu entry described in the shipped bundle, then trace how the server thread.meta-updated completion is consumed. Done means the new title appears in the thread, the pending regeneration state clears, and the menu action becomes enabled for another regeneration.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.