Skip to content

fix(server): retry automatic thread title generation - #8087

Merged
juliusmarminge merged 4 commits into
pingdotgg:mainfrom
Bil0000:t3code/fix/thread-title-generation
Aug 29, 2026
Merged

fix(server): retry automatic thread title generation#8087
juliusmarminge merged 4 commits into
pingdotgg:mainfrom
Bil0000:t3code/fix/thread-title-generation

Conversation

@Bil0000

@Bil0000 Bil0000 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

What Changed

Automatic thread title generation now retries twice with exponential backoff before giving up.

  • maybeGenerateThreadTitleForFirstTurn wraps generateThreadTitle in Effect.retry (2 retries, 2s exponential backoff).
  • Added a regression test: the first attempt fails with a TextGenerationError, the second succeeds, and the thread ends up with the generated title.

No behavior change on the success path, and no change to the prompts, the regeneration path, or any other text generation operation.

Why

Automatic titles are generated exactly once, on the first turn, and the result is dropped on failure. Before that turn starts, the web and mobile clients already seed the thread with a placeholder title truncated from the first user message. So a single failed generation leaves the thread permanently named after the raw prompt text ("There are some spacing issues in the too..."), with only a server-side logWarning to show for it.

This is not rare. On a long-running instance, server logs show 32 failed automatic title generations over 14 days:

  • 21 x Claude CLI request timed out. (the text generation CLI has a 180s ceiling, and a single title call measured 60–80s on a loaded machine, so contention pushes it over)
  • 11 x transient CLI failures, all Failed to authenticate: OAuth session expired and could not be refreshed

Every one of those threads still carries the truncated first message as its title in projection_threads.

Both failure classes are transient, so a bounded retry is the smallest fix that makes the title actually land. The existing guard after generation is unchanged: the generated title is still only applied when the thread title is still the default or still equals the client's titleSeed, so a title the user renamed during the backoff is never overwritten.

Known limitation: this does not make title generation faster, and a thread whose generation fails all three times still keeps the placeholder. Reducing the per-call latency and surfacing a persistent failure to the user are separate changes.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes (no UI change)
  • I included a video for animation/interaction changes (not applicable)

Note

Retry thread title generation in ProviderCommandReactor up to 2 times

Wraps the generateThreadTitle call site in ProviderCommandReactor.make with a retry policy using exponential backoff (2s, then 4s). The title generation now retries up to 2 additional times on transient failures before giving up. The test in ProviderCommandReactor.test.ts is updated to verify a first-call failure is retried and the second call succeeds.

Macroscope summarized 0c94e6d.

Automatic thread titles are generated once, on the first turn, and the
result is discarded on failure. The web and mobile clients seed the
thread with a placeholder title truncated from the first user message
before the turn starts, so a single failed generation leaves the thread
permanently named after the raw prompt text.

Server logs on a long-running instance show this failing regularly:
over 14 days, 32 automatic title generations failed, two thirds with
"Claude CLI request timed out." and the rest with transient CLI errors
such as a failed OAuth refresh. Every one of those threads still carries
the truncated first message as its title.

Retry the generation twice with exponential backoff. The existing
post-generation guard still applies, so a title the user renamed in the
meantime is never overwritten.
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1359c27c-21a2-42c0-8595-b9c914e72e31

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 24, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 24, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 0c94e6d

Macroscope's review found this PR approvable — This is a narrow resilience fix to existing background thread-title generation, adding at most two delayed retries after provider failures and leaving other paths unchanged. The included test covers recovery from a transient timeout, with no schema, infrastructure, security, billing, or default-setting changes.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg

t3dotgg commented Aug 28, 2026

Copy link
Copy Markdown
Member

Note

🤖 GPT-5.6 Sol responding on behalf of Theo

We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together.

This addresses a real but low-impact failure where the first automatic title attempt can be lost. We do not have a current reproduction that justifies keeping this full retry patch in the active queue.

If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed.

@t3dotgg t3dotgg closed this Aug 28, 2026

@Bil0000 Bil0000 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove useless code comments

Comment thread apps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
@macroscopeapp
macroscopeapp Bot dismissed their stale review August 29, 2026 09:57

Dismissing prior approval to re-evaluate 1e2fdef

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 29, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review August 29, 2026 15:11

Dismissing prior approval to re-evaluate 0c94e6d

@juliusmarminge
juliusmarminge merged commit fc262f1 into pingdotgg:main Aug 29, 2026
25 checks passed
@Bil0000

Bil0000 commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Ponytail finding fixed: the retry regression duplicated the existing title-generation integration test. The transient failure now lives in that test, and the one-use retry constants are inlined. Net: -44 lines. Verified with all 49 ProviderCommandReactor tests, server typecheck, lint, and format.

AspireOne pushed a commit to AspireOne/t3code that referenced this pull request Aug 29, 2026
bcotrim pushed a commit to bcotrim/mognet that referenced this pull request Aug 30, 2026
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Aug 31, 2026
## What's Changed
* Remove Messages Glass Lab experiment by @juliusmarminge in pingdotgg/t3code#8599
* Require human review for pull requests changing product defaults by @juliusmarminge in pingdotgg/t3code#8603
* fix(codex): avoid quadratic app-server input buffering by @juliusmarminge in pingdotgg/t3code#8605
* fix(mobile): stabilize iOS header item transitions by @juliusmarminge in pingdotgg/t3code#8607
* chore(mobile): upgrade to Expo SDK 57 by @juliusmarminge in pingdotgg/t3code#8609
* fix(mobile): harden native header toolbar items by @juliusmarminge in pingdotgg/t3code#8611
* fix(server): stop querying Claude context usage after turns by @t3dotgg in pingdotgg/t3code#8610
* chore: vouch ryanrhughes by @t3dotgg in pingdotgg/t3code#8613
* feat(web): attach PDFs, ZIPs, and other files to a turn by @t3dotgg in pingdotgg/t3code#8236
* feat(web): keybinding settings as settings rows by @StiensWout in pingdotgg/t3code#8532
* feat: let an environment publish themes as a file by @ryanrhughes in pingdotgg/t3code#8569
* fix(web): clean up provider settings list and editor by @StiensWout in pingdotgg/t3code#8504
* fix(web): keep project picker popup inside the sidebar by @SunkenInTime in pingdotgg/t3code#8627
* fix(mobile): prevent header overflow and back-button artifacts by @juliusmarminge in pingdotgg/t3code#8624
* fix(server): retry automatic thread title generation by @Bil0000 in pingdotgg/t3code#8087
* fix(client-runtime): refresh edited pull request comments by @Bil0000 in pingdotgg/t3code#8094
* fix(web): four composer spacing defects by @Bil0000 in pingdotgg/t3code#8090
* perf(desktop): skip duplicate browser updates by @Bil0000 in pingdotgg/t3code#8018
* fix(web): render nested markdown images correctly by @flamboh in pingdotgg/t3code#8501
* fix(web): unify activity logs and composer banners by @juliusmarminge in pingdotgg/t3code#8693
* fix(mobile): reduce dev-client reload and Metro startup cost by @juliusmarminge in pingdotgg/t3code#8694
* revert(web): restore previous composer banners by @t3dotgg in pingdotgg/t3code#8733
* test(web): remove tests for unreachable helpers by @t3-code[bot] in pingdotgg/t3code#8738
* feat(mobile): update tool summaries and chat transitions by @juliusmarminge in pingdotgg/t3code#8793
* feat(web): play video attachments in chat by @Bil0000 in pingdotgg/t3code#8688
* fix(web,mobile): snooze menu no longer offers the same wake time twice by @vitalyiegorov in pingdotgg/t3code#8741
* fix(grok): allow model changes in existing threads by @ahmed-besic in pingdotgg/t3code#8392
* feat(mobile): pick, share, and receive files in threads by @t3dotgg in pingdotgg/t3code#8237
* fix(web): reduce title bar scroll fade height by @maria-rcks in pingdotgg/t3code#8799
* fix(windows): strip quotes from repaired PATH by @UtkarshUsername in pingdotgg/t3code#8746
* fix(web): open agent images in expanded preview by @maria-rcks in pingdotgg/t3code#8807
* fix(git): follow repository instructions in generated source control text by @maria-rcks in pingdotgg/t3code#8804
* fix(server): stop overpricing cached Claude tokens by @SunkenInTime in pingdotgg/t3code#8806
* fix(web): keep image preview above sidebar control by @maria-rcks in pingdotgg/t3code#8811
* fix(web): keep right panel synced with agent edits by @maria-rcks in pingdotgg/t3code#8803
* fix(web,mobile): render Codex citations and artifact templates by @Yash-Singh1 in pingdotgg/t3code#8584
* chore: add Windows setup script to t3.json by @UtkarshUsername in pingdotgg/t3code#8814
* fix(web): fold interim turn responses by @maria-rcks in pingdotgg/t3code#8828
* fix(web): use circle alert for failed tool calls by @maria-rcks in pingdotgg/t3code#8840
* feat(mobile): add offline iPhone voice input by @t3dotgg in pingdotgg/t3code#8614
* fix(web): prevent pull request metadata overlap by @MatthewFeroz in pingdotgg/t3code#8790

## New Contributors
* @ryanrhughes made their first contribution in pingdotgg/t3code#8569
* @ahmed-besic made their first contribution in pingdotgg/t3code#8392
* @MatthewFeroz made their first contribution in pingdotgg/t3code#8790

**Full Changelog**: pingdotgg/t3code@v0.0.36...v0.0.37

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants