Repository navigation
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/server
Steps to reproduce
- Use a Claude thread from the mobile app, and have the agent start a background shell or a background agent (here
gh pr checks --watch). - Without changing the model, effort or any option, send a message to the same thread from the web or desktop client while that work still runs.
Expected behavior
The message goes to the live Claude process. Nothing about the model or its settings changed.
Actual behavior
Every message fails with:
Claude is still running background agents or commands, and this model or setting change would end them. Wait for them to finish, or press Stop, then send the message again.
The thread accepts nothing until the background work ends on its own. Stop doesn't help either, which is tracked separately.
Cause
The two clients send the same Normal speed differently. Mobile omits fastMode. The web composer always adds fastMode: false (withImplicitFastModeDefault in apps/web/src/components/chat/composerProviderState.tsx).
compileClaudeModelSelection (apps/server/src/claudeModelOptions.ts) keeps the two apart: settings is {} for one and { fastMode: false } for the other, so queryIdentity differs. openQuery in ClaudeAdapterV2.ts then sees a selection change. Since #14726 it refuses that change with ClaudeBackgroundWorkBlocksQueryReplacementError whenever background work runs. Before #14726 it silently restarted the process, which killed the work.
From the affected thread's run records:
| Runs | Sent from | modelSelection.options |
Result |
|---|---|---|---|
| 1–14 | mobile | none | completed |
| 15–16 | server (continuation after the update restart) | none | completed; run 16 started the background shell |
| 17–19 | web | [{ id: "fastMode", value: false }] |
failed with the error above |
Suggested fix
Compile an unset fastMode as false for models that support it. That is the Normal speed the web composer already sends, so both clients produce the same settings and the same query identity. It's a one-line change in compileClaudeModelSelection; the guard from #14726 stays as it is. I can open the PR.
Impact
Blocks work completely
Version or commit
t3@0.0.46-nightly.20261004.2644 (main 8fb068c)
Environment
Linux host (systemd service). macOS desktop client and the mobile app on the same thread.
Screenshots, recordings, or supporting files
The model and effort are unchanged (Claude Opus 5.5, Medium · 1M), yet each message is refused as a setting change:
Once the shell ended, the next message showed a context handoff from Claude Opus 5.5 to Claude Opus 5.5, again with no model change:
Workaround
Keep sending from the client the background work was started from, or wait until the work ends.
Related
- fix(server): Claude model changes no longer kill running background agents #14726 added the guard that turns this mismatch into a hard refusal.
- Claude thread permanently fails with "No conversation found with session ID" after fresh-session fallback resumes a newly minted id #15103: after the shell ended, this thread failed with "No conversation found with session ID", which is that issue.


Activity
vitalyiegorov commentedon Oct 4, 2026
PR opened: #15473. For models that expose fast mode, an unset
fastModenow compiles as Normal, which is what the web composer already sends. Mobile and web then produce the same query identity, and the #14726 guard stays as it is.juliusmarminge commentedon Oct 4, 2026
Note
Grok responding on behalf of Julius.
Triage
Thanks @vitalyiegorov for the run records and the root-cause write-up; they made this quick to confirm. I checked it on
8fb068c498(the nightly you reported against), and the code matches your table.What I found
fastMode: false.withImplicitFastModeDefaultinapps/web/src/components/chat/composerProviderState.tsxadds that option for every model with a fast-mode descriptor. Mobile only keeps the options that were actually selected, so a Claude thread started there has nofastModeoption.compileClaudeModelSelection(apps/server/src/claudeModelOptions.ts) keeps them apart: an omitted value stays out ofsettings, whilefalsebecomes{ fastMode: false }.queryIdentityincludes that object, so the two sends don't match.openQueryinClaudeAdapterV2.tsonly reuses the live process when the identity matches. While that process has background work and isn't stopping, the mismatch raisesClaudeBackgroundWorkBlocksQueryReplacementError, which is the message you saw. Opus 5.5 exposesfastModein the bundled catalog, so this model hits it.isClaudeProviderContinuationTurn), which is why runs 15 and 16 completed with no options.Likely fix area
Some options:
fastModetofalseincompileClaudeModelSelectionfor models that expose fast mode, so omitted and explicit Normal produce the same identity. A real switch to Fast would still change the identity, so the fix(server): Claude model changes no longer kill running background agents #14726 guard would keep blocking it while background work runs. That's the approach in your open PR fix(claude): a thread with background work no longer refuses messages sent from another client #15473.A maintainer will decide on the fix direction.
CoreInfusion commentedon Oct 4, 2026
Same failure through a second path, with no mobile client involved. This one is likely common with orchestration v2:
t3_thread_launchwithmodelSelection: {instanceId, model}and nooptions. Later turns come from an outside client throughorchestration.dispatchCommand/message.dispatchwithoutmodelSelection. The live Claude query therefore runs withsettings: {}in itsqueryIdentity.options: [{id: "fastMode", value: false}], givingsettings: {fastMode: false}, a differentselectionKey.openQuerytreats it as a model/setting change and throwsClaudeBackgroundWorkBlocksQueryReplacementError. Three messages in a row were refused; nothing had changed.Cause as seen in the bundle:
compileClaudeModelSelectionaddsfastModetosettingsonly when the option is present, so an explicit default value and a missing option produce differentqueryIdentitystrings. Normalizing defaults before building the identity would cover both the mobile/web case in this issue and the MCP/outside-client case.Version: 0.0.46-nightly.20261003.2632 (Linux server), claudeAgent / claude-opus-5-5. The thread then broke for good the way #15103 describes (details there).