[Bug] Claude 1M context marker fails: uppercase [1M] written + fallback model lacks toggle
#3,679 opened on Jun 4, 2026
Description
[Bug] Claude 1M context marker fails: uppercase [1M] written + fallback model lacks toggle
概要 / Summary
cc-switch 在为 Claude Code 配置 1M context 时存在两个相关问题,导致用户勾选"声明支持 1M"后 1M context 实际并未启用:
- Bug 1:写入的 marker 是大写
[1M],但 Claude Code 官方只识别小写[1m] - Bug 2:默认兜底模型(ANTHROPIC_MODEL)输入框旁边没有"声明支持 1M"勾选框,而它的优先级高于 alias 字段,会反向覆盖三角色的设置
环境(已验证):
- cc-switch v3.16.1(main 当前 HEAD
ce53826) - Claude Code v2.1.161
- macOS 25.4.0
- model: claude-opus-4-7
Bug 1:Marker 写入用大写 [1M]
位置
src/components/providers/forms/hooks/useModelState.ts:17
export const CLAUDE_ONE_M_MARKER = "[1M]";
表现
- 在 cc-switch 模型映射区,为 Sonnet/Opus 勾选"声明支持 1M"
- 保存并启动 Claude Code
/context命令输出仍显示200K tokens分母,不是预期的1M- 检查
~/.claude/settings.json,发现写入的是claude-opus-4-7[1M](大写) - 手动改成
claude-opus-4-7[1m](小写)后重启 Claude Code,/context立刻变为1m tokens
根因
Claude Code 官方文档 model-config 原文明确要求小写:
Append
[1m]to the model ID to enable the 1M context window for a pinned model.
源码读取路径(第 20、25 行)都用 .toLowerCase() 容错,所以已经写入的大写值能被正确识别和 strip——这隐藏了写入侧的 bug:
// L20 — 读取容错
return model.trimEnd().toLowerCase().endsWith("[1m]");
// L25 — strip 容错
if (!trimmedEnd.toLowerCase().endsWith("[1m]")) return model;
// L32 — 写入硬编码大写!
return enabled ? `${base}${CLAUDE_ONE_M_MARKER}` : base;
修复
一行修改(见 patch 01-bug1-marker-lowercase.patch):
-export const CLAUDE_ONE_M_MARKER = "[1M]";
+export const CLAUDE_ONE_M_MARKER = "[1m]";
Bug 2:默认兜底模型缺"声明支持 1M"勾选框
位置
src/components/providers/forms/ClaudeFormFields.tsx:924
表现
模型映射区为 Sonnet/Opus/Haiku 三个角色提供"声明支持 1M"勾选框(截图见下),但底部"默认兜底模型"(ANTHROPIC_MODEL)输入框旁边没有同样的勾选框。
普通用户即使在 Sonnet/Opus 勾选了 1M(在叠加 Bug 1 修复后写出正确的 [1m]),只要兜底模型未带 [1m],1M 仍不会启用。
根因
Claude Code 官方文档 env-vars 原文:
ANTHROPIC_MODELoverrides themodelsetting
兜底模型优先级高于所有 alias 解析(ANTHROPIC_DEFAULT_OPUS_MODEL 等)。当用户在三角色上勾选 1M(写入 _DEFAULT_OPUS_MODEL=...[1m]),但兜底字段没带 [1m] 后缀时,兜底硬覆盖所有 alias,1M 不会被启用。
这跟 Bug 1 叠加时影响放大:
- 用户在 cc-switch UI 完成所有勾选 → 觉得"配置好了"
- 实际启动 Claude Code → 1M 没启用
- 调查后才会发现:UI 没暴露兜底字段的 1M 开关
社区已有用户反馈过类似问题(discussion #2693 中用户提到:"我的默认兜底模型是 deepseek-v4-pro[1m] cc-switch 选择时没有后面的 [1m] 这是我自己加的")。
修复
UI 加 checkbox + state 联动(见 patch 02-bug2-fallback-1m-checkbox.patch),约 25 行 inline 改动,复用现有 i18n key providerForm.modelOneMLabel,不引入新依赖、不重构数组。
修复验证(本地)
Patch 1 单独应用后:
| 操作 | 结果 |
|---|---|
| 在 Sonnet/Opus 勾选 1M | settings.json 写入 ...[1m] ✓(之前是 [1M]) |
Bug 2 仍未修,兜底字段无 [1m] |
1M 仍不启用 ✗(被 ANTHROPIC_MODEL 覆盖) |
Patch 1 + Patch 2 一起应用后:
| 操作 | 结果 |
|---|---|
| 在 Sonnet/Opus 勾选 1M + 兜底字段勾选 1M | settings.json 全部 ...[1m] ✓ |
重启 Claude Code,/context |
显示 1M tokens 分母 ✓ |
transcript.model 字段 |
claude-opus-4-7[1m](带后缀) ✓ |
建议
两个 bug 强相关,建议合并到同一个 PR 修复。Patch 1 是 1 行修改,Patch 2 是 ~25 行 UI inline。
如果要拆,至少 Bug 1 应该单独 cherry-pick 优先合入——它对所有用户都是无副作用的安全修复。