openclaw - ✅(Solved) Fix openclaw doctor rewrites agents.defaults.model.primary from claude-cli/* to anthropic/*, breaking CLI session continuity [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#80402Fetched 2026-05-11 03:15:04
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
2
Timeline (top)
cross-referenced ×2commented ×1

openclaw doctor (and the post-update repair flow) silently rewrites agents.defaults.model.primary from claude-cli/claude-opus-4-7 to anthropic/claude-opus-4-7. The Anthropic provider is not configured on this host, so every turn falls back to the claude-cli provider — but OpenClaw's session-binding logic keys off the configured provider, not the actual fallback. The result is that stored CLI session IDs no longer match on-disk transcripts, and a fresh CLI subprocess is spawned on every resume.

This is the claude-cli analogue of #79306 (which describes the same class of rewrite for openai-codex/* -> openai/*). The user-visible failure mode here is different (session continuity rather than billing route), but the underlying behavior — doctor "normalizing" a provider-prefixed model ID into a different provider — appears to be the same bug.

Environment:

  • OpenClaw 2026.5.7 (eeef486)
  • Linux x64, Node 22.22.2
  • Configured primary: claude-cli/claude-opus-4-7
  • Anthropic provider: not configured (no API key, no profile)

Error Message

  1. If doctor believes a configured provider is invalid, it should warn and prompt rather than silently substituting a different provider.

Root Cause

Because the configured provider is now anthropic but no Anthropic provider is reachable, runtime falls back to claude-cli for actual generation — but session-binding still keys off the configured provider. Symptoms:

Fix Action

Fixed

PR fix notes

PR #80408: fix(doctor): preserve claude-cli/* model refs instead of rewriting to anthropic/*

Description (problem / solution / changelog)

Summary

doctor --fix was silently rewriting agents.defaults.model.primary from claude-cli/claude-opus-4-7 to anthropic/claude-opus-4-7 because claude-cli appeared in LEGACY_RUNTIME_MODEL_PROVIDER_ALIASES and normalizeLegacyRuntimeAgentModelConfig treated every matched alias as a legacy ref to rewrite.

Unlike codex-cli and google-gemini-cli (which are legacy aliases for their canonical openai/* and google/* counterparts), claude-cli/* is the canonical provider prefix users explicitly configure for the Claude CLI integration. Rewriting it breaks session continuity: stored CLI session IDs key off the configured provider, so every turn spawns a fresh Claude subprocess instead of resuming the prior conversation.

Root cause: normalizeLegacyRuntimeAgentModelConfig unconditionally used migrated.ref (the anthropic/* form) whenever migrateLegacyRuntimeModelRef returned non-null. The legacyProvider field was already available on the return value — this fix checks it and skips the rewrite for claude-cli.

Changes

  • src/commands/doctor/shared/legacy-config-core-normalizers.ts: guard normalizeLegacyRuntimeAgentModelConfig with legacyProvider === "claude-cli" check; skip rewrite and return the original ref unchanged. codex-cli and google-gemini-cli continue to migrate as before.
  • src/commands/doctor-legacy-config.migrations.test.ts: update the existing claude-cli migration test to assert the correct behavior (preserve ref, zero changes reported).

Test

pnpm vitest run src/commands/doctor-legacy-config.migrations.test.ts

33/33 pass. The updated test asserts claude-cli/claude-opus-4-7 survives normalizeCompatibilityConfigValues unchanged with zero reported changes.

Fixes #80402.

Changed files

  • src/commands/doctor-config-analysis.test.ts (modified, +19/-0)
  • src/commands/doctor-legacy-config.migrations.test.ts (modified, +10/-16)
  • src/commands/doctor/shared/legacy-config-core-normalizers.ts (modified, +13/-9)
  • src/config/zod-schema.agent-runtime.ts (modified, +1/-0)
  • src/config/zod-schema.ts (modified, +1/-0)

PR #80413: fix(doctor): preserve claude-cli/* model refs instead of rewriting to anthropic/*

Description (problem / solution / changelog)

Summary

doctor --fix was silently rewriting agents.defaults.model.primary from claude-cli/claude-opus-4-7 to anthropic/claude-opus-4-7 because claude-cli appeared in LEGACY_RUNTIME_MODEL_PROVIDER_ALIASES and normalizeLegacyRuntimeAgentModelConfig treated every matched alias as a legacy ref to rewrite.

Unlike codex-cli and google-gemini-cli (true legacy aliases for their canonical openai/* and google/* counterparts), claude-cli/* is the canonical provider prefix users explicitly configure for the Claude CLI integration. Rewriting it breaks session continuity: stored CLI session IDs key off the configured provider, so every turn spawns a fresh Claude subprocess instead of resuming the prior conversation.

Root cause: normalizeLegacyRuntimeAgentModelConfig unconditionally used migrated.ref (the anthropic/* form) whenever migrateLegacyRuntimeModelRef returned non-null. The legacyProvider field was already available on the return value — this fix checks it and skips the rewrite for claude-cli.

Changes

  • src/commands/doctor/shared/legacy-config-core-normalizers.ts: guard with legacyProvider === "claude-cli" check; skip rewrite and return original ref unchanged.
  • src/commands/doctor-legacy-config.migrations.test.ts: update existing test to assert correct preservation behavior (zero changes reported).

Real behavior proof

Behavior or issue addressed: openclaw doctor --fix rewrites agents.defaults.model.primary from claude-cli/claude-opus-4-7 to anthropic/claude-opus-4-7, breaking CLI session continuity — every turn spawns a fresh Claude subprocess instead of resuming the prior conversation.

Real environment tested: Node.js v22, Linux, openclaw monorepo from source with this patch applied locally.

Exact steps or command run after fix:

openclaw doctor --fix
pnpm vitest run src/commands/doctor-legacy-config.migrations.test.ts

Evidence after fix: After running openclaw doctor --fix on a config containing claude-cli/claude-opus-4-7 as primary, the config file was NOT modified — the ref was preserved as-is. The new regression test preserves claude-cli primary refs unchanged — not a legacy alias to rewrite validates this at the normalization layer. Other CLI aliases (google-gemini-cli, codex-cli) continue to migrate as before.

Test Files  1 passed (1)
     Tests  33 passed (33)

Observed result after fix: Running openclaw doctor --fix with a claude-cli/* primary model ref now exits with zero config changes reported. 33/33 unit tests pass, including the new regression test verifying claude-cli refs are preserved.

What was not tested: End-to-end openclaw doctor --fix CLI run on a live gateway instance with the full plugin stack active (no local Claude CLI gateway available for full integration test), but the fix is at the normalization layer that doctor --fix calls directly.

Fixes #80402.

Changed files

  • apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift (modified, +4/-0)
  • extensions/discord/src/actions/runtime.test.ts (modified, +4/-4)
  • src/commands/doctor-config-analysis.test.ts (modified, +19/-0)
  • src/commands/doctor-legacy-config.migrations.test.ts (modified, +10/-16)
  • src/commands/doctor/shared/legacy-config-core-normalizers.ts (modified, +13/-9)
  • src/config/zod-schema.agent-runtime.ts (modified, +1/-0)
  • src/config/zod-schema.ts (modified, +1/-0)

Code Example

"agents.defaults.model.primary": "claude-cli/claude-opus-4-7"

---

"agents.defaults.model.primary": "anthropic/claude-opus-4-7"
RAW_BUFFERClick to expand / collapse

Summary

openclaw doctor (and the post-update repair flow) silently rewrites agents.defaults.model.primary from claude-cli/claude-opus-4-7 to anthropic/claude-opus-4-7. The Anthropic provider is not configured on this host, so every turn falls back to the claude-cli provider — but OpenClaw's session-binding logic keys off the configured provider, not the actual fallback. The result is that stored CLI session IDs no longer match on-disk transcripts, and a fresh CLI subprocess is spawned on every resume.

This is the claude-cli analogue of #79306 (which describes the same class of rewrite for openai-codex/* -> openai/*). The user-visible failure mode here is different (session continuity rather than billing route), but the underlying behavior — doctor "normalizing" a provider-prefixed model ID into a different provider — appears to be the same bug.

Environment:

  • OpenClaw 2026.5.7 (eeef486)
  • Linux x64, Node 22.22.2
  • Configured primary: claude-cli/claude-opus-4-7
  • Anthropic provider: not configured (no API key, no profile)

What goes wrong

1. doctor rewrites the model provider prefix

Intended config:

"agents.defaults.model.primary": "claude-cli/claude-opus-4-7"

After running openclaw doctor (or after an update that triggers the equivalent repair flow):

"agents.defaults.model.primary": "anthropic/claude-opus-4-7"

These two provider IDs are not equivalent:

  • claude-cli/claude-opus-4-7 => local Claude CLI subprocess, with session-id bookkeeping under ~/.openclaw/.../claude-cli/...
  • anthropic/claude-opus-4-7 => Anthropic API provider, requires API key / configured profile

2. Downstream session bookkeeping breaks

Because the configured provider is now anthropic but no Anthropic provider is reachable, runtime falls back to claude-cli for actual generation — but session-binding still keys off the configured provider. Symptoms:

  • The resume check claudeCliSessionTranscriptHasContent fails after each ~10-minute idle close with reason=missing-transcript.
  • A fresh CLI subprocess is spawned on each turn, with no carry-over.
  • User experience: the agent appears to "forget" prior conversation after a short idle window, even though daily transcripts on disk are intact.

3. doctor may also silently mutate adjacent fields

In the same repair cycle, plugins.slots.memory was observed to change from hindsight-openclaw to memory-core. Not investigated in depth, but flagging it so any audit of the rewrite logic can cover that field too.

Recovery

Manually reverting agents.defaults.model.primary back to claude-cli/claude-opus-4-7 in ~/.openclaw/openclaw.json and restarting the gateway restores session continuity.

Expected behavior

  1. doctor should not rewrite a user-set model.primary across provider domains. claude-cli/* and anthropic/* are not interchangeable, the same way openai-codex/* and openai/* are not (per #79306).
  2. If doctor believes a configured provider is invalid, it should warn and prompt rather than silently substituting a different provider.
  3. Post-update flows should validate that the chosen provider is actually configured (API key present, profile selected, etc.) before writing it.

Impact

  • Loss of session continuity — agent appears amnesic after short idle gaps.
  • Failure mode is hard to diagnose because the agent still produces output (via the silent fallback), so users don't immediately suspect a config rewrite.
  • Recovery requires manual config inspection.

Suggested fixes

  • Treat provider IDs as stable, semantically meaningful identifiers during normalization (echoes the suggestion in #79306).
  • Add a doctor check that flags mismatches between configured model.primary provider and available providers/profiles, and reports them rather than auto-rewriting.
  • If doctor must change model.primary, write a clear summary line to its output: "Changed agents.defaults.model.primary: <old> -> <new> (reason: ...)" so the user can spot the rewrite immediately.

Related

  • #79306 — same class of rewrite, openai-codex/* -> openai/*
  • #75720 — auto-onboard / plugin presets overwriting agents.defaults.model.primary

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

  1. doctor should not rewrite a user-set model.primary across provider domains. claude-cli/* and anthropic/* are not interchangeable, the same way openai-codex/* and openai/* are not (per #79306).
  2. If doctor believes a configured provider is invalid, it should warn and prompt rather than silently substituting a different provider.
  3. Post-update flows should validate that the chosen provider is actually configured (API key present, profile selected, etc.) before writing it.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix openclaw doctor rewrites agents.defaults.model.primary from claude-cli/* to anthropic/*, breaking CLI session continuity [2 pull requests, 1 comments, 2 participants]