[Bug]: Composer applies the settings default's options to a thread saved without options#23497

opened12d agobyFf4llenz

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

Split out from #16406, as asked there. #19341 fixed the refused send; this is the part that is still open.

  1. In Settings → General → New threads, set Model to Claude Opus 5.5 and use its traits picker to choose High effort.
  2. Create a thread whose model selection has no options. For example, from an agent call t3_thread_launch with modelSelection: { instanceId: "claudeAgent", model: "claude-opus-5-5" }. The server stores the selection as given and opens Claude at the catalog default, Medium.
  3. Open the thread in the web or desktop app. Don't touch the model or trait controls. Send a message.

Expected behavior

The composer shows Medium, the effort the thread runs with. A send with untouched controls keeps Medium.

Actual behavior

The composer shows High and sends effort: high. The server applies it (since #19341, even while background agents run), so the thread switches to High although nobody chose that for it. Before #19341 the same send was refused while background agents ran (#16406).

deriveEffectiveComposerModelState (apps/web/src/composerDraftStore.ts) resolves the model as thread → project, but the options as draft → thread → project. A thread saved without options therefore takes the options of the project or settings default.

Threads created in the composer aren't affected, because a new draft already uses the project default as its thread selection. Mobile resolves draft ?? thread as one selection and isn't affected either.

Impact

Minor bug or occasional failure

Version or commit

main @ 5ffe045931

Environment

Web and desktop clients, Claude provider. First seen on desktop 0.0.46-nightly.20261003.2610 (#16406).

Logs or stack traces

shell
1# main @ 5ffe045931 with the resolver test from #16546, without its fix
2FAIL src/modelSelection.test.ts > instance-scoped model selection > composer model option precedence > does not inherit settings options for an optionless existing thread
3+ "value": "high",
4Tests 1 failed | 29 passed (30)

Workaround

Pick the effort in the composer before the first send, or have the launching agent pass effort in t3_thread_launch.

Related

  • Fix: #16546 makes the options fallback match the model fallback. On main @ 5ffe045931 its test file passes with the fix (30/30) and fails without it, as above.
  • #21140 edits the same expression for draft seeds on started threads. It keeps the thread → project options fallback, so it doesn't fix this, and the two PRs will conflict there.

Filed by Claude Opus 5.5 in Claude Code (T3 Code) on behalf of @f4llenz.