Skip to content

[Bug]: Claude Desktop 1.46388.4 cannot switch models within an active conversation #3782

Closed

Description

@ZhenyuXiao

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

  1. Start the OpenCodex local proxy on http://127.0.0.1:10100.
  2. In the OpenCodex Claude Desktop profile, configure at least these two routes:
    • native/gpt-5.6-sol, with the Desktop alias claude-opus-4-8-20260304.
    • native/gpt-5.6-terra, with the Desktop alias claude-opus-4-8-20261213.
  3. Run ocx claude desktop apply, then fully quit and reopen Claude Desktop.
  4. Create a new third-party-gateway conversation, select the route for native/gpt-5.6-sol, and send a message. The response succeeds.
  5. In the same active conversation, select the route for native/gpt-5.6-terra in Claude Desktop's footer model picker and send another message.
  6. In that same conversation, enter /model claude-opus-4-8-20261213 and send another message.
  7. 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-20261213 also 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:

  1. Claude Desktop not sending the changed model ID;
  2. the embedded Claude worker retaining its initial --model argument; and
  3. 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.

Related reports

Activity

  1. coderabbitai commented on Sep 6, 2026

    @coderabbitai
    Contributor
    ⚠️ Possible Duplicate Issue(s)

    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. github-actions commented on Sep 6, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  3. lidge-jun commented on Sep 6, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 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.ts resolveInboundModel - 요청에 실린 모델 문자열만 별칭/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 비교가 필요

    메인테이너의 판단이 필요한 지점

    • Logs → requestedModel이 /model 직후에도 옛 별칭이면 Desktop 쪽(와이어/워커) 문제로 보고 Desktop 3P: Model picker change at the bottom not reflecting in the session (only switched by /model command) #546 과 같이 upstream+문서 유지할지, 아니면 Desktop 1.46388.4 전용 안내를 가이드에 더 쓸지
    • requestedModel은 새 별칭인데 실제 upstream 라우트가 안 바뀌면 resolveInboundModel / Desktop 3P 별칭 테이블 버그로 이슈를 열어둘지
    • 리포터에게 2.44/2.45 라인으로 올린 뒤 같은 재현을 다시 받을지, 2.43.0 로그만으로도 충분한지

    너의 추천
    닫지 말고 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이 작성했습니다

  4. ZhenyuXiao commented on Sep 7, 2026

    @ZhenyuXiao
    Author

    Retest after upgrading OpenCodex to v2.45.0.

    Environment:

    • OpenCodex: v2.45.0
    • Client: Claude Desktop
    • Provider: OpenCodex-compatible API provider

    Test result:

    1. Start a new Claude Desktop conversation with model A.
    2. Use the Claude Desktop model selector to switch to model B.
    3. Also tested /model <model-id>.
    4. Send another message and inspect the OpenCodex request logs.

    The Claude Desktop UI shows the newly selected model, but the actual request does not change:

    • requestedModel remains model A
    • The subsequent requests continue using model A
    • The model switch is not propagated to OpenCodex

    This 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?

  5. ZhenyuXiao commented on Sep 7, 2026

    @ZhenyuXiao
    Author

    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-20260308
    • native/gpt-5.6-sol → family=opus, alias=claude-opus-4-8-20260304
    • native/gpt-5.6-terra → family=sonnet, alias=claude-opus-4-8-20261213
    • native/gpt-6-astra → family=fable, alias=claude-opus-4-8-20260627

    All 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-2026MMDD alias shape, even when its profile family is haiku, sonnet, or fable. The profile validator also rejects a manually changed alias such as claude-haiku-4-8-20260308.

    Observed behavior remains:

    • Claude Desktop UI changes the selected model/family.
    • The next request still has the original requestedModel.
    • OpenCodex therefore continues routing the first model.

    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?

  6. lidge-jun commented on Sep 7, 2026

    @lidge-jun
    Owner

    Docs update on dev (#3884, merge 74089fdc3): the Claude Code/Desktop guide now states that the /model workaround can also fail on the reported Desktop build, because the incoming requestedModel is fixed by the client before the request reaches the proxy — which matches your retest (requestedModel remains 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.

  7. ZhenyuXiao commented on Sep 7, 2026

    @ZhenyuXiao
    Author

    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 at http://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-2026MMDD alias shape, even when the profile assignment family is haiku, sonnet, or fable.

    With OpenCodex, the UI changes but requestedModel remains 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

    Image

    This shows CC Switch running in Model Mapping mode. The Claude tiers are mapped as follows:

    • Sonnet / Opus / Fable → deepseek-v4-pro
    • Haiku → deepseek-v4-flash

    This confirms that the two Claude model roles are intentionally mapped to different DeepSeek models.

    Screenshot 2 — Claude Desktop model-switch confirmation

    Image

    When switching from the cached deepseek-v4-flash session to deepseek-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

    Image

    After switching with /model, Claude Desktop reports different active Claude models in the conversation (Haiku 4.5 and then Fable 5). The footer shows deepseek-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

    Image

    This shows the Claude Desktop model list configured by CC Switch. The model IDs use family-specific aliases such as claude-fable-5 and claude-haiku-4-5, while their display names map to deepseek-v4-pro and deepseek-v4-flash.

    Comparison with OpenCodex:

    • CC Switch version: v3.20.1
    • CC Switch gateway: http://127.0.0.1:15721/claude-desktop
    • OpenCodex gateway: http://127.0.0.1:10100
    • CC Switch successfully changes the upstream model in the existing conversation.
    • OpenCodex still keeps the original requestedModel after 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.

  8. Ingwannu commented on Sep 8, 2026

    @Ingwannu
    Owner

    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.

  9. added
    priority: P2Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue,
    on Sep 24, 2026
  10. 122yjs commented on Sep 25, 2026

    @122yjs
    Contributor

    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

    • OpenCodex: 2.65.0
    • Claude Desktop: 2.9939.2 (macOS)
    • Claude Code: 2.1.281
    • Integration: local Desktop 3P gateway, static managed profile

    I correlated four layers without recording prompt content:

    1. Desktop LocalSessions.setModel
    2. the embedded Claude Code process's parsed control requests
    3. OpenCodex request logs / logs explain
    4. the next assistant message's model metadata

    Date-alias → date-alias changes are suppressed before Claude Code

    KST Requested Desktop model Claude Code received set_model? Next routed model
    21:58:45 claude-opus-4-8-20261013 no previous alibaba-token-plan-intl/deepseek-v4.1-flash
    22:07:26 claude-opus-4-8-20260620 no previous DeepSeek route
    22:09:20 claude-opus-4-8-20260816 no previous DeepSeek route
    22:27:36 claude-opus-4-8-20261022 no previous gpt-6-luna route

    At each failed timestamp Desktop logged LocalSessions.setModel, but the running CLI received only get_context_usage, not set_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_model arrived. 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_model arrived, the Qwen validation request returned 200, and the next real turn used alibaba-token-plan-intl/qwen3.8-flash.
    • claude-opus-4-8-20260518 → claude-opus-5-5: set_model arrived 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_model cases.

    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 -YYYYMMDD suffix. applyModelChange returns early when the normalized current and requested model IDs are equal.

    Therefore all of these distinct OpenCodex routes compare equal inside Desktop:

    claude-opus-4-8-20261009 -> claude-opus-4-8
    claude-opus-4-8-20261013 -> claude-opus-4-8
    claude-opus-4-8-20260620 -> claude-opus-4-8
    claude-opus-4-8-20261022 -> claude-opus-4-8
    

    The successful [1m] control is consistent with that implementation: the date is no longer terminal, so claude-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-YYYYMMDD aliases (src/claude/desktop-profile.ts). By contrast, the non-profile helper in src/claude/desktop-3p.ts already 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:

    1. two routed models receive aliases that remain distinct after Desktop's terminal-date normalization;
    2. real Anthropic IDs remain exact;
    3. existing date aliases still decode during migration;
    4. effort/family and [1m] behavior remain intact.

    I am preparing a test-first draft PR against current main and will link it here.

  11. added a commit that references this issue on Sep 26, 2026
    5cedfcb
  12. lidge-jun commented on Sep 26, 2026

    @lidge-jun
    Owner

    Addressed on dev by #5862, merged in #5904 (merge bc90209): Desktop profile aliases are now emitted as p<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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority: P2Medium: provider/client-specific bug with a workaround, bounded enhancement tied to a tracked issue,

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions