🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

fix(coderd): stop manual title generation from writing to chat_messages - #27087

Merged
ethanndickson merged 4 commits into
mainfrom
ethan/fix-chatd-stuck-title-generation
Jul 13, 2026
Merged

fix(coderd): stop manual title generation from writing to chat_messages#27087
ethanndickson merged 4 commits into
mainfrom
ethan/fix-chatd-stuck-title-generation

Conversation

@ethanndickson

@ethanndickson ethanndickson commented Jul 8, 2026

Copy link
Copy Markdown
Member

Coder Agents chats could get stuck showing "Thinking" forever when a title regenerate/propose request ran while a generation was in flight.

Manual title generation recorded token cost by inserting a hidden assistant message into chat_messages and immediately soft-deleting it. Triggers on that table sync chats.history_version to snapshot_version, so this out-of-band write broke the history_version fence of an in-flight generation task, killing it without a replacement and leaving the chat stuck in running.

Remove the accounting path entirely; AI Gateway already records title-call usage in aibridge_interceptions/aibridge_token_usages. The manual title endpoints no longer write to chat_messages at all, and new regression tests assert history_version stays untouched. Note this intentionally drops title-generation cost from chatd's chat-level cost surfaces; it still counts against the user's AI budget via AI Gateway.

Closes CODAGT-595

@linear-code

linear-code Bot commented Jul 8, 2026

Copy link
Copy Markdown

CODAGT-595

@ethanndickson
ethanndickson marked this pull request as ready for review July 8, 2026 09:34
@ethanndickson

Copy link
Copy Markdown
Member Author

@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: 2959572b94

ℹ️ 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
@ethanndickson

ethanndickson commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

@codex review

re: Track manual title spend in chat usage limits

Valid catch, but this is the intentional tradeoff of the fix rather than an oversight, and the blast radius is smaller than it looks:

checkUsageLimit still runs before every title generation, so a user who is over their chat limit is still blocked from these endpoints. The gap is only that title-call spend by an under-limit user no longer advances the counter.
Per-call cost is tightly bounded: input is truncated, output is capped at 256 tokens, and it uses the cheap short-text model. Exploiting this meaningfully would take thousands of calls, which is a rate-limiting concern.
Deployments using AI budgets are unaffected. Title calls route through AI Gateway, which records usage and enforces budgets independently.
The suggested fix (persisting the usage somewhere the limiter can read) is exactly the code path that caused the production incident: the only safe place the chat limiter reads from is chat_messages, and writing accounting rows there from outside the state machine is what broke the task fence. We can't have the limiter read AI Gateway spend instead without double-counting, since regular generation is already recorded in both chat_messages and the gateway tables.

The clean fix is to rebase chat usage limits onto AI Gateway spend data entirely, which is a redesign, not something I want to fold into this bug fix. Accepting the gap here, and it's called out in the PR description.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: 2959572b94

ℹ️ 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".

@ethanndickson
ethanndickson requested a review from mafredri July 8, 2026 10:07
@ethanndickson
ethanndickson force-pushed the ethan/fix-chatd-stuck-title-generation branch from 4226d1a to e3dad7f Compare July 9, 2026 04:28
Comment thread coderd/x/chatd/chatd.go Outdated
Manual title generation (RegenerateChatTitle/ProposeChatTitle) recorded
token cost by inserting a hidden assistant message into chat_messages and
immediately soft-deleting it. Both statements fire AFTER-STATEMENT triggers
that sync chats.history_version to snapshot_version. This was the only
chat_messages writer outside the chatstate state machine, so it bumped
history_version without advancing snapshot_version or publishing a state
update.

An in-flight generation task captures history_version at spawn and verifies
it via a fence at commit. The out-of-band bump made that fence fail, exiting
the task via the non-retryable path that performs no cleanup because it
assumes a replacement task exists. None is spawned, so the chat stayed
running forever and the UI showed "Thinking" indefinitely.

Remove the chatd-side accounting path entirely. AI Gateway (aibridge)
already records title-call usage independently in aibridge_interceptions
and aibridge_token_usages, so the hidden-message accounting was redundant.
persistManualTitle now only performs the optimistic title write.

This intentionally removes title-generation cost and tokens from chatd's
own chat-level cost surfaces (GetChatCostSummary and the spend-limit query
paths); that usage now lives only in AI Gateway data.
…CTURE.md

Drop the redundant WARNING comment on InsertChatMessages (and its
generated propagation into querier.go/queries.sql.go) and the standalone
ARCHITECTURE.md paragraph. The rule that every chat_messages write must go
through a state machine transition now lives as a single sentence alongside
the existing runtime-code guardrail in the message revision section.
@ethanndickson
ethanndickson force-pushed the ethan/fix-chatd-stuck-title-generation branch from e3dad7f to 240b118 Compare July 13, 2026 05:59
@ethanndickson
ethanndickson merged commit ea45540 into main Jul 13, 2026
27 of 29 checks passed
@ethanndickson
ethanndickson deleted the ethan/fix-chatd-stuck-title-generation branch July 13, 2026 06:50
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants