Repository navigation
[Bug]: Claude Desktop 1.46388.4 cannot switch models within an active conversation #3782
Description
Summary
When using Claude Desktop through the OpenCodex third-party gateway, I can select one of the configured models when creating a conversation and responses work normally. However, changing the model later within the same conversation does not affect subsequent requests. The /model <id> workaround also does not work in my environment.
Model switching works correctly with Claude Code using the same OpenCodex configuration.
Environment
- OpenCodex: 2.43.0
- Claude Desktop:
Claude 1.46388.4 (50e62f) 2026-09-05T01:57:47.000Z - Operating system: Windows
- Integration: Claude Desktop third-party gateway profile
- Gateway:
http://127.0.0.1:10100 - Configured models: 16 OpenCodex routes
Reproduction
- Start the OpenCodex local proxy on
http://127.0.0.1:10100. - In the OpenCodex Claude Desktop profile, configure at least these two routes:
native/gpt-5.6-sol, with the Desktop aliasclaude-opus-4-8-20260304.native/gpt-5.6-terra, with the Desktop aliasclaude-opus-4-8-20261213.
- Run
ocx claude desktop apply, then fully quit and reopen Claude Desktop. - Create a new third-party-gateway conversation, select the route for
native/gpt-5.6-sol, and send a message. The response succeeds. - In the same active conversation, select the route for
native/gpt-5.6-terrain Claude Desktop's footer model picker and send another message. - In that same conversation, enter
/model claude-opus-4-8-20261213and send another message. - Repeat the model switch in Claude Code using the same OpenCodex configuration.
Actual behavior
- Selecting a model when creating a new Claude Desktop conversation works.
- The footer picker changes visually, but the existing conversation continues to use the model selected when the conversation/worker was initialized.
/model claude-opus-4-8-20261213also does not change the model in my environment.- Claude Code can switch models successfully with the same OpenCodex setup.
Expected behavior
Changing the model in the Claude Desktop footer picker, or using /model <id>, should make the next request use the newly selected route while preserving the existing conversation history.
Diagnostics requested
Please advise which sanitized diagnostics would distinguish between:
- Claude Desktop not sending the changed model ID;
- the embedded Claude worker retaining its initial
--modelargument; and - OpenCodex receiving the new model ID but resolving it to the old route.
The OpenCodex documentation mentions /model <id> as a workaround, but that workaround does not work for me. This differs from #546, where /model reportedly worked. It is also related to #603, which describes the same footer-picker behavior.
Activity
coderabbitai commentedon Sep 6, 2026
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
github-actions commentedon Sep 6, 2026
Issue reopened
The report now contains the information required by the automated check. Thanks for updating it.
lidge-jun commentedon Sep 6, 2026
리뷰 · 우선순위 50 / 80
이 이슈는 Claude Desktop 앱(빌드 1.46388.4)에서 OpenCodex 서드파티 게이트웨이로 대화할 때, 대화를 새로 만들 때 고른 모델은 잘 가는데, 이미 열린 대화 안에서 아래쪽 모델 선택(footer picker)이나 /model 로 바꾸면 다음 요청이 새 모델로 안 바뀐다는 보고입니다. 같은 OpenCodex 설정으로 Claude Code에서는 모델 전환이 된다고 했고, 환경은 Windows, OpenCodex 2.43.0, 게이트웨이 http://127.0.0.1:10100, 라우트 16개입니다.
지금 dev HEAD(7d8523e, 패키지 2.45.0) 기준으로 보면, Desktop 3P는
src/claude/desktop-profile.ts와ocx claude desktop apply로 프로필을 쓰고, 들어오는 요청의 모델 문자열은src/claude/inbound-model-options.ts의resolveInboundModel이 별칭 → Desktop 3P 별칭 → modelMap 순으로 풀어서 실제 provider/model 라우트로 보냅니다. 프록시는 Claude Desktop의 "지금 픽커에 뭐가 선택됐는지" 이벤트를 따로 받지 않습니다. 요청 본문에 실려 온 모델 id만 봅니다.그래서 예전에 같은 증상으로 닫힌 #546 / #603 에서는 이렇게 정리했습니다. footer picker는 Desktop 세션(워커) 쪽에 초기 모델이 남아 있어서 와이어에 새 id를 안 실을 수 있다. OpenCodex가 그 상태를 억지로 덮어쓰면, 사용자가 대화마다 고른 모델을 프록시가 무시하게 되어 더 위험하다. 문서화된 우회는 이미 열린 Desktop 3P 대화에서는 /model 를 쓰고, GUI Logs → requestedModel 로 다음 요청에 새 id가 왔는지 확인하는 것입니다. 가이드에도 그대로 있습니다(
docs-site/src/content/docs/guides/claude-code.md의 Desktop footer / /model 절).이번 #3782 가 새롭게 중요한 점은, 리포터가 문서 우회인 /model 조차 안 된다고 한 부분입니다. #546 때는 /model 이 requestedModel 을 바꿔 주는 걸로 프록시 쪽 라우팅이 정상임을 확인했습니다. 지금은 (1) Desktop이 바꾼 id를 아예 안 보내는지, (2) Desktop 임베디드 워커가 초기 모델을 계속 쓰는지, (3) OpenCodex는 새 id를 받았는데 옛 라우트로 풀리는지 — 이 세 가지를 Logs로 가려야 합니다. 새 대화에서만 되고 Claude Code에서는 되는 패턴은, 대개 (1)(2) 쪽 Desktop 클라이언트 동작에 가깝고, (3)이면 resolveInboundModel / Desktop 별칭 테이블 쪽을 봐야 합니다.
리포트에 쓴 Desktop 별칭 예시는 claude-opus-4-8-20260304 / claude-opus-4-8-20261213 처럼 날짜 형태 접미사입니다. 가이드 표의 기본 형태는 claude-opus-4-8-<3글자 base36>(예: claude-opus-4-8-ncb)이지만, 프로필에 날짜형 별칭을 직접 넣은 구성도 가능합니다. 새 대화 선택이 성공했다는 건 그 별칭 → native/gpt-5.6-sol / native/gpt-5.6-terra 매핑 자체는 apply 시점에는 살아 있다는 뜻입니다. 문제는 "대화가 이미 열린 뒤"의 전환입니다.
우선순위 50인 이유: 실제 사용자 통증은 분명하고 재현 절차도 잘 적혀 있지만, 현재 dev 방향(릴리스 2.44→2.45 오픈, Windows lifecycle / Cursor blob / credential 쪽)의 블로커는 아닙니다. 먼저 Logs로 (1)(2)(3)을 가르고, (1)(2)면 업스트림 Desktop 동작으로 #546 과 같은 줄에 두고 문서/진단만 보강하는 쪽이 맞고, (3)이면 그때 proxy 쪽 버그로 올리면 됩니다.
docs-site/src/content/docs/guides/claude-code.md(Desktop footer / /model) - 이미 열린 대화는 /model + Logs→requestedModel이 공식 우회인데, 이번 리포트는 그 우회가 실패한다고 해서 진단이 필수다src/claude/inbound-model-options.tsresolveInboundModel- 요청에 실린 모델 문자열만 별칭/3P/map으로 품. Desktop 픽커 상태는 여기서 안 봄src/claude/desktop-profile.ts/ocx claude desktop apply- 새 대화 시작 시 모델 목록·별칭은 여기서 쓰이지만, 열린 대화 중 전환 이벤트를 프록시가 구독하지는 않음#546 / #603 - footer picker sticky는 업스트림 Desktop으로 문서화·종료. 이번 건은 /model 실패 주장이 추가된 재발/회귀 후보
리포트 환경 OpenCodex 2.43.0 vs 현재 dev 2.45.0 - 최신(또는 곧 나가는 2.44 preview/stable)에서 같은 Logs 비교가 필요
메인테이너의 판단이 필요한 지점
너의 추천
닫지 말고 bug 유지. 리포터에게 한 번만 더 부탁: (가) /model claude-opus-4-8-20261213 직후 메시지 한 번의 Logs → requestedModel 값(새 별칭인지 옛 별칭인지), (나) 같은 시각의 라우트/프로바이더, (다) 가능하면 OpenCodex를 2.44/2.45로 올린 뒤 같은 비교. requestedModel이 안 바뀌면 #546 과 같이 Desktop 세션 sticky로 문서 안내를 보강하고 이슈는 upstream 쪽으로 정리. requestedModel만 바뀌고 라우트가 안 바뀌면 inbound-model-options / Desktop 3P 별칭 쪽을 버그로 파고든다. 지금은 그 한 줄 증거 없이 프록시 수정을 시작하지 말 것.
이 댓글은 grok-bot이 작성했습니다
ZhenyuXiao commentedon Sep 7, 2026
Retest after upgrading OpenCodex to v2.45.0.
Environment:
Test result:
/model <model-id>.The Claude Desktop UI shows the newly selected model, but the actual request does not change:
requestedModelremains model AThis still reproduces after upgrading to OpenCodex v2.45.0.
Based on the logs, the issue appears to occur before OpenCodex routing: Claude Desktop does not send the updated model ID for the existing conversation. Could you confirm whether Claude Desktop keeps the initial model pinned in its active conversation worker, and whether there is any supported workaround or diagnostic flag?
ZhenyuXiao commentedon Sep 7, 2026
Additional evidence after upgrading to OpenCodex v2.45.0.
The Desktop profile contains 16 routes with unique aliases. For example:
native/gpt-5.6-luna→ family=haiku, alias=claude-opus-4-8-20260308native/gpt-5.6-sol→ family=opus, alias=claude-opus-4-8-20260304native/gpt-5.6-terra→ family=sonnet, alias=claude-opus-4-8-20261213native/gpt-6-astra→ family=fable, alias=claude-opus-4-8-20260627All 16 aliases are unique, and the profile defaults point to different routes for Opus, Fable, Sonnet, and Haiku. Therefore this is not an alias-collision or multiple-routes-to-one-alias problem.
However, every non-Anthropic route is exposed with the
claude-opus-4-8-2026MMDDalias shape, even when its profile family ishaiku,sonnet, orfable. The profile validator also rejects a manually changed alias such asclaude-haiku-4-8-20260308.Observed behavior remains:
requestedModel.This suggests a possible Claude Desktop 3P compatibility issue with OpenCodex's unified Opus-shaped aliases: family metadata changes in the profile, but the active conversation worker may keep the initial model ID. Could the maintainer confirm whether the Desktop worker normalizes or pins these aliases by the Opus-shaped prefix, and whether exposing family-specific aliases is supported or intentionally avoided?
lidge-jun commentedon Sep 7, 2026
Docs update on
dev(#3884, merge74089fdc3): the Claude Code/Desktop guide now states that the/modelworkaround can also fail on the reported Desktop build, because the incomingrequestedModelis fixed by the client before the request reaches the proxy — which matches your retest (requestedModelremains model A). That part is client-owned, so no proxy routing change is planned here; leaving the issue open for a Desktop-side fix or a new reproduction that shows the proxy receiving the switched model.ZhenyuXiao commentedon Sep 7, 2026
Important comparative result:
The same Claude Desktop installation and user environment can switch models successfully when using CC Switch as the local gateway at
http://127.0.0.1:15721/claude-desktop. The failure only occurs when the Claude Desktop profile points to OpenCodex athttp://127.0.0.1:10100.Therefore this does not appear to be a universal Claude Desktop limitation. It is more specifically a compatibility difference between Claude Desktop and the OpenCodex 3P profile/gateway behavior.
CC Switch exposes family-specific Claude-shaped routes (Sonnet, Opus, and Haiku) and maps each request to its configured upstream model. OpenCodex v2.45.0 exposes all non-Anthropic routes using the
claude-opus-4-8-2026MMDDalias shape, even when the profile assignment family ishaiku,sonnet, orfable.With OpenCodex, the UI changes but
requestedModelremains the initial model. With CC Switch, switching the model results in the expected new route.This suggests that the OpenCodex alias/profile format or Desktop 3P integration may trigger the pinned-worker behavior, while CC Switch's family-specific route names avoid it. Could this be reconsidered as an OpenCodex/Claude Desktop integration compatibility issue rather than a general client-owned limitation?
Additional comparison with CC Switch 3.20.1:
CC Switch repository:
https://github.com/farion1231/cc-switch
The following screenshots were captured in the same Claude Desktop environment.
Screenshot 1 — CC Switch model mapping configuration
This shows CC Switch running in Model Mapping mode. The Claude tiers are mapped as follows:
deepseek-v4-prodeepseek-v4-flashThis confirms that the two Claude model roles are intentionally mapped to different DeepSeek models.
Screenshot 2 — Claude Desktop model-switch confirmation
When switching from the cached
deepseek-v4-flashsession todeepseek-v4-pro, Claude Desktop displays a confirmation dialog explaining that the whole session will be switched on the next message.This confirmation dialog appears when using CC Switch, but does not appear when switching models through the OpenCodex gateway.
Screenshot 3 — Successful model switch with CC Switch
After switching with
/model, Claude Desktop reports different active Claude models in the conversation (Haiku 4.5 and then Fable 5). The footer showsdeepseek-v4-pro.This demonstrates that the same Claude Desktop installation successfully switched from the DeepSeek Flash mapping to the DeepSeek Pro mapping when using CC Switch.
Screenshot 4 — CC Switch Claude Desktop model list
This shows the Claude Desktop model list configured by CC Switch. The model IDs use family-specific aliases such as
claude-fable-5andclaude-haiku-4-5, while their display names map todeepseek-v4-proanddeepseek-v4-flash.Comparison with OpenCodex:
v3.20.1http://127.0.0.1:15721/claude-desktophttp://127.0.0.1:10100requestedModelafter the model switch.This suggests that the difference may be related to the Claude Desktop profile/model alias format or gateway integration behavior, rather than a universal Claude Desktop limitation.
Ingwannu commentedon Sep 8, 2026
The same-client comparison is meaningful new evidence. This should remain open as an OpenCodex/Desktop integration compatibility investigation, not be dismissed as a universal inability of Desktop to switch models. I have not reproduced the Desktop behavior locally or independently validated the CC Switch implementation.
Current dev still intentionally generates claude-opus-4-8 aliases for routed models (src/claude/desktop-3p.ts:133-140), and desktop-profile.ts validates that alias shape. The source comment ties that choice to Desktop effort handling. Your family-specific comparison is therefore a useful lead, but simply changing the prefix could regress effort controls or existing profile assignments; a patch needs to exercise both switching and those contracts.
The next decisive evidence is a same-version comparison of the model field actually sent after the switch, rather than the picker label alone: whether the switch-confirmation dialog appeared, whether the next request model changed, and whether the resolved upstream target followed it. No prompts, credentials, raw captures, or full profile/config files are needed. If you already have those scalar observations, they are enough to refine this investigation; do not repeatedly restore or recreate your setup just to collect them. No fix or client-owned root cause is being claimed yet.
122yjs commentedon Sep 25, 2026
I can now narrow this down to a reproducible alias-identity collision in Claude Desktop, rather than a generic sticky-worker or OpenCodex routing failure.
Fresh reproduction
I correlated four layers without recording prompt content:
LocalSessions.setModellogs explainDate-alias → date-alias changes are suppressed before Claude Code
set_model?claude-opus-4-8-20261013alibaba-token-plan-intl/deepseek-v4.1-flashclaude-opus-4-8-20260620claude-opus-4-8-20260816claude-opus-4-8-20261022gpt-6-lunarouteAt each failed timestamp Desktop logged
LocalSessions.setModel, but the running CLI received onlyget_context_usage, notset_model. OpenCodex therefore never had a new model request to route.Controls that did reach Claude Code
claude-opus-5-5→claude-opus-4-8-20260224:set_modelarrived. The Bai/GLM validation request then failed separately with HTTP 400 (max_tokens must be greater than 2).claude-opus-4-8-20260224→claude-opus-4-8-20260620[1m]:set_modelarrived, the Qwen validation request returned 200, and the next real turn usedalibaba-token-plan-intl/qwen3.8-flash.claude-opus-4-8-20260518→claude-opus-5-5:set_modelarrived but Anthropic validation returned 429. Desktop rolled back to the previous alias; the following date-alias selection was then suppressed as above.The 400/429 errors are real but are not the cause of the no-
set_modelcases.Root cause in the current Desktop bundle
Claude Desktop's local-session manager normalizes model identity before deciding whether to send a control request. Its normalization removes a terminal
-YYYYMMDDsuffix.applyModelChangereturns early when the normalized current and requested model IDs are equal.Therefore all of these distinct OpenCodex routes compare equal inside Desktop:
The successful
[1m]control is consistent with that implementation: the date is no longer terminal, soclaude-opus-4-8-20260620[1m]does not collapse to the same value.OpenCodex side of the compatibility issue
The managed profile path still allocates and validates only
claude-opus-4-8-YYYYMMDDaliases (src/claude/desktop-profile.ts). By contrast, the non-profile helper insrc/claude/desktop-3p.tsalready generates a letter-first three-character suffix (claude-opus-4-8-<code>) and documents that it cannot be confused with a real/date-suffixed model ID.That makes the managed date namespace incompatible with Desktop's current model-equivalence rule even though every full alias is unique in the profile.
Proposed fix direction
Use non-date synthetic aliases for managed Desktop profiles as well, while retaining reverse decoding for existing date aliases so old profiles/sessions do not suddenly route to Anthropic. The change should include tests proving that:
[1m]behavior remain intact.I am preparing a test-first draft PR against current
mainand will link it here.fix(claude): avoid Desktop alias date collisions (#5862)
lidge-jun commentedon Sep 26, 2026
Addressed on
devby #5862, merged in #5904 (merge bc90209): Desktop profile aliases are now emitted asp<base36day>wire ids, so Desktop's date stripping can no longer collapse a routed model onto a real dated Anthropic id (the likely reason switching had no effect). If switching models inside a conversation still fails on the next release, please reopen with the Desktop version and the model ids shown.