Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: avoid 500 when generating chat title from rename dialog and remove unused endpoint - #28306

Merged
f0ssel merged 9 commits into
mainfrom
codagt-278-fix-generate-title-500
Aug 25, 2026
Merged

fix: avoid 500 when generating chat title from rename dialog and remove unused endpoint#28306
f0ssel merged 9 commits into
mainfrom
codagt-278-fix-generate-title-500

Conversation

@f0ssel

@f0ssel f0ssel commented Aug 19, 2026

Copy link
Copy Markdown
Member

Problem

Clicking Generate in the Rename Chat dialog runs manual chat-title
generation. It runs a single model under a 30s deadline; a slow provider hit
the deadline and returned context deadline exceeded, which bubbled up wrapped
to the propose-title handler and fell through to a raw 500 that leaked
the wrapped chain in detail:

{"message":"Failed to generate chat title.",
 "detail":"generate manual title: generate structured title: tool-based generation failed: context deadline exceeded"}

Fixes CODAGT-278.

Change

Two parts:

1. Friendly error mapping (coderd/exp_chats.go)

Translate manual-title pipeline errors instead of returning a raw 500, matching
with errors.Is so the deeply-wrapped errors are detected:

  • Title timeout → 504 "Title generation timed out. Try again or rename manually."
    The 504 branch keys off the chatd.ErrManualTitleTimedOut sentinel, which
    chatd attaches only when the title-generation deadline actually expired, so a
    provider failure that merely wraps an unrelated transport deadline keeps its
    500 surface.
  • context.Canceled499, and only when the request context itself is
    canceled, so a provider error wrapping context.Canceled (e.g. an upstream
    401) on a live request is not misreported as a client-closed request.

Genuine, unrelated failures keep their existing 500 surface, and the translated
copy does not leak the raw error detail. No frontend change is required: the
rename dialog already renders the API message.

The generation path itself is unchanged: a single model (deployment override,
else the preferred short-text model, else the chat's own model) under the
existing 30s deadline.

2. Remove the redundant /title/regenerate endpoint

The frontend only calls POST /chats/{chat}/title/propose (rename dialog);
nothing calls /title/regenerate anymore, and both funneled into the same
generation path since #24820. Removed the route, handler, codersdk client
method, and the persist/broadcast path only it used (persistManualTitle,
regenerateChatTitleWithStore). Ported the paste-only-chat coverage to the
propose suite and added the missing swagger annotations for the propose
endpoint so it now appears in the API reference.

Tests

  • TestMaybeWriteManualTitleTimeoutErr: 504 for the tagged title timeout,
    499 only with a canceled request context, and fall-through preserving the
    500 for untagged deadline wraps, live-context cancels, and unrelated errors.
  • TestProposeChatTitle (10 subtests), including the paste-only-chat coverage
    ported from the removed regenerate suite.

Notes for reviewers

Prior art: PR #25424 (Dean, reviewed by Ethan + Codex; closed, never merged)

The earlier #25424 approached this by walking multiple models with fallback.
A multi-model candidate walk was prototyped on this branch and then removed to
keep the change minimal: this PR only maps errors to friendly statuses and
deletes the redundant endpoint, leaving the single-model generation path as it
is on main.

Generated by Coder Agents on behalf of @f0ssel.

Clicking Generate in the rename dialog (or Regenerate) runs manual chat
title generation under an internal deadline. When the model call times
out, the error ("context deadline exceeded") bubbled up to the propose
and regenerate handlers and fell through to a raw 500 that leaked the
wrapped error chain.

Translate context.DeadlineExceeded to 504 with a friendly retry message
and context.Canceled to 499 (client closed request) in both the
propose-title and regenerate-title handlers, matching by errors.Is so
the wrapped deadline error is detected. Genuine, unrelated failures keep
their existing 500 surface.

Generated by Coder Agents.
@linear-code

linear-code Bot commented Aug 19, 2026

Copy link
Copy Markdown

CODAGT-278

@f0ssel

f0ssel commented Aug 19, 2026

Copy link
Copy Markdown
Member Author

This PR intentionally scopes to the error-mapping fix, which fully resolves
the reported 500. A larger reliability enhancement, a multi-model fallback walk
(try preferred small models, then the chat's own model, with an overall budget
and per-attempt deadline so a single slow provider no longer times out the
request), is deferred to a follow-up because:

It is an enhancement, not the fix. The 504/499 mapping resolves the
user-visible defect and behaves correctly for single-model deployments, where
a walk is inert.
Converting the single-model resolver into a candidate list entangles ~6
mocked-DB unit tests and the configCache fallback path; that rewrite carries
regression risk best kept out of this focused change.
Open UX question: a ~90s multi-model walk behind a manual button means a long
spinner versus a fast, friendly 504 with retry. Worth settling before
investing in the walk.

@ethanndickson please let me know if you think going all the way to the small model enhancement is the move here and I can keep going. I'm just defaulting to a minimal change first given release timing.

@f0ssel
f0ssel requested a review from ethanndickson August 19, 2026 16:25
@f0ssel
f0ssel marked this pull request as ready for review August 19, 2026 18:53

@ethanndickson ethanndickson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No issues with this change but do we know why we were seeing timeouts in the first place?

They cropped up prior to the chatd refactor, so it's entirely possible the root cause is already fixed

@f0ssel

f0ssel commented Aug 20, 2026

Copy link
Copy Markdown
Member Author

My understanding is just very slow model responses, most likely because it's using a big expensive model with high effort. I think it's still possible to hit in that scenario since this does not include any logic to select a smaller model if possible.

@ibetitsmike

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 90d6322cb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread coderd/exp_chats.go Outdated
f0ssel added 3 commits August 24, 2026 13:42
…tion

Manual chat title generation (rename dialog Generate and Regenerate)
previously ran a single model under a 30s deadline. A slow provider hit
the deadline and failed the request, which the handler now surfaces as a
504.

Walk the enabled preferred short-text models the user has credentials
for, then the chat's own model, bounded by an overall 90s budget with a
30s per-attempt deadline. Fall through to the next candidate only on
per-attempt timeout or chatretry-classified transient errors; stop on
non-retryable errors (auth, config) so real failures still surface.

When the context is canceled after a candidate has already failed, the
walker surfaces ctx.Err() instead of the stale candidate error, so the
handler maps caller cancellation to 499 and overall-budget expiry to 504
rather than a stale 500.

Fallback models resolve lazily so a run that succeeds on the first
candidate never constructs the others. Replaces the single-model
resolveManualTitleModel (and the now-unused
selectPreferredConfiguredShortTextModelConfig) with
resolveManualTitleCandidates.

Generated by Coder Agents.
…te-title-500

# Conflicts:
#	coderd/x/chatd/chatd.go
#	coderd/x/chatd/quickgen.go
#	coderd/x/chatd/quickgen_internal_test.go
#	coderd/x/chatd/title_override_internal_test.go
@f0ssel
f0ssel marked this pull request as draft August 24, 2026 17:52
@f0ssel

f0ssel commented Aug 24, 2026

Copy link
Copy Markdown
Member Author

@codex review

@f0ssel
f0ssel marked this pull request as ready for review August 24, 2026 18:13

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 74c7c78842

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread coderd/x/chatd/chatd.go Outdated
Comment thread coderd/exp_chats.go Outdated
…llback

Address two review findings:
- Map manual title errors to 504 only when a title deadline actually
  expired, via the chatd.ErrManualTitleTimedOut sentinel, so provider
  failures that merely wrap a transport deadline keep the 500 surface.
- Append the chat's own model as the final walk candidate when preferred
  short-text models exist, so the walk can still succeed when every
  preferred candidate fails. It skips itself when it duplicates an
  already-attempted preferred config.
@f0ssel
f0ssel marked this pull request as draft August 24, 2026 18:29
The frontend only uses POST /chats/{chat}/title/propose (rename dialog);
nothing calls /title/regenerate anymore. Remove the endpoint, its
codersdk client method, the chatd persist/broadcast path it alone used
(persistManualTitle, regenerateChatTitleWithStore), and its tests. Port
the paste-only-chat coverage to the propose suite and add the missing
swagger annotations for the propose endpoint so it appears in the API
reference.
@github-actions

Copy link
Copy Markdown
Contributor

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

@f0ssel f0ssel changed the title fix(coderd): avoid 500 when generating chat title from rename dialog fix: avoid 500 when generating chat title from rename dialog Aug 24, 2026
…ation

Restore the single-model manual title path (resolveManualTitleModel and
selectPreferredConfiguredShortTextModelConfig) and delete the candidate
walk (titlewalk.go). Keep the 30s generation deadline and the
ErrManualTitleTimedOut sentinel so the handler still maps genuine title
timeouts to a friendly 504 and caller cancellation to 499.

Generated by Coder Agents.
@f0ssel

f0ssel commented Aug 24, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: a7b88c7e40

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@f0ssel

f0ssel commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

I've increased the scope of this PR to include removing the unused and redundant endpoint discussed in the Linear issue attached slack thread. Adding @jaaydenh for a safety and sanity check on this

@f0ssel
f0ssel marked this pull request as ready for review August 25, 2026 00:37
@f0ssel
f0ssel requested a review from jaaydenh August 25, 2026 00:38
@f0ssel f0ssel changed the title fix: avoid 500 when generating chat title from rename dialog fix: avoid 500 when generating chat title from rename dialog and remove unused endpoint Aug 25, 2026
@f0ssel
f0ssel merged commit eedc0ec into main Aug 25, 2026
44 checks passed
@f0ssel
f0ssel deleted the codagt-278-fix-generate-title-500 branch August 25, 2026 10:52
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants