openclaw - 💡(How to fix) Fix `openclaw doctor --fix` / runtime model routing breaks OpenRouter nested model ids like `openrouter/deepseek/deepseek-v4-pro`

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…

A configured agent using OpenRouter nested model ids can be routed as if the nested vendor namespace were the provider. Example intended model ref:

openrouter/deepseek/deepseek-v4-pro

Expected runtime routing:

provider=openrouter
baseUrl=https://openrouter.ai/api/v1
model=deepseek/deepseek-v4-pro

Observed after upgrade/doctor/session normalization:

provider=deepseek
model=deepseek/deepseek-v4-pro or deepseek-v4-pro

This sends the request to native DeepSeek provider/auth instead of OpenRouter, causing either No API key found for provider "deepseek" or HTTP 401 from api.deepseek.com.

Root Cause

A configured agent using OpenRouter nested model ids can be routed as if the nested vendor namespace were the provider. Example intended model ref:

openrouter/deepseek/deepseek-v4-pro

Expected runtime routing:

provider=openrouter
baseUrl=https://openrouter.ai/api/v1
model=deepseek/deepseek-v4-pro

Observed after upgrade/doctor/session normalization:

provider=deepseek
model=deepseek/deepseek-v4-pro or deepseek-v4-pro

This sends the request to native DeepSeek provider/auth instead of OpenRouter, causing either No API key found for provider "deepseek" or HTTP 401 from api.deepseek.com.

Fix Action

Fix / Workaround

Local workaround

With that alias, openclaw agent ... --json succeeds, but runtime metadata reports provider=deepseek, proving the workaround is absorbing the reparsed provider rather than preserving the intended openrouter provider.

Code Example

openrouter/deepseek/deepseek-v4-pro

---

provider=openrouter
baseUrl=https://openrouter.ai/api/v1
model=deepseek/deepseek-v4-pro

---

provider=deepseek
model=deepseek/deepseek-v4-pro or deepseek-v4-pro

---

{
  "agents": {
    "list": [
      {
        "id": "deepseek-main",
        "model": "openrouter/deepseek/deepseek-v4-pro"
      }
    ]
  },
  "models": {
    "providers": {
      "openrouter": {
        "baseUrl": "https://openrouter.ai/api/v1",
        "auth": "api-key",
        "api": "openai-completions",
        "models": [
          {
            "id": "deepseek/deepseek-v4-pro",
            "api": "openai-completions",
            "input": ["text"],
            "contextWindow": 128000
          }
        ]
      }
    }
  }
}

---

openclaw agent --agent deepseek-main --session-id smoke-test --message "ping" --timeout 60 --json

---

provider=openrouter
model=deepseek/deepseek-v4-pro

---

provider=deepseek
model=deepseek-v4-pro

---

provider=deepseek
model=deepseek/deepseek-v4-pro

---

"models": {
  "providers": {
    "deepseek": {
      "baseUrl": "https://openrouter.ai/api/v1",
      "auth": "api-key",
      "api": "openai-completions",
      "apiKey": {
        "source": "file",
        "provider": "openrouter",
        "id": "value"
      },
      "models": [
        {
          "id": "deepseek/deepseek-v4-pro",
          "api": "openai-completions",
          "input": ["text"],
          "contextWindow": 128000
        }
      ]
    }
  }
}
RAW_BUFFERClick to expand / collapse

Upstream Issue Draft: nested provider model ids are reparsed as provider ids

Title

openclaw doctor --fix / runtime model routing breaks OpenRouter nested model ids like openrouter/deepseek/deepseek-v4-pro

Version

  • OpenClaw 2026.5.12-beta.1 (8046b5e)
  • Linux x64, node 24.15.0

Summary

A configured agent using OpenRouter nested model ids can be routed as if the nested vendor namespace were the provider. Example intended model ref:

openrouter/deepseek/deepseek-v4-pro

Expected runtime routing:

provider=openrouter
baseUrl=https://openrouter.ai/api/v1
model=deepseek/deepseek-v4-pro

Observed after upgrade/doctor/session normalization:

provider=deepseek
model=deepseek/deepseek-v4-pro or deepseek-v4-pro

This sends the request to native DeepSeek provider/auth instead of OpenRouter, causing either No API key found for provider "deepseek" or HTTP 401 from api.deepseek.com.

Minimal config shape

{
  "agents": {
    "list": [
      {
        "id": "deepseek-main",
        "model": "openrouter/deepseek/deepseek-v4-pro"
      }
    ]
  },
  "models": {
    "providers": {
      "openrouter": {
        "baseUrl": "https://openrouter.ai/api/v1",
        "auth": "api-key",
        "api": "openai-completions",
        "models": [
          {
            "id": "deepseek/deepseek-v4-pro",
            "api": "openai-completions",
            "input": ["text"],
            "contextWindow": 128000
          }
        ]
      }
    }
  }
}

Reproduction

  1. Configure an agent with model: "openrouter/deepseek/deepseek-v4-pro" and an OpenRouter provider whose catalog model id is deepseek/deepseek-v4-pro.
  2. Run openclaw doctor --fix or reuse sessions whose persisted rows contain normalized model/provider fields.
  3. Run:
openclaw agent --agent deepseek-main --session-id smoke-test --message "ping" --timeout 60 --json
  1. Inspect result.meta.agentMeta.provider / executionTrace.winnerProvider and the selected base provider.

Expected

OpenClaw should preserve the first segment as provider and the remainder as the model id:

provider=openrouter
model=deepseek/deepseek-v4-pro

No native DeepSeek provider/auth should be required.

Actual

The nested model id can be reparsed later as:

provider=deepseek
model=deepseek-v4-pro

or as:

provider=deepseek
model=deepseek/deepseek-v4-pro

depending on persisted session/model state. The request then targets the native DeepSeek provider instead of OpenRouter.

Local workaround

Register a provider alias:

"models": {
  "providers": {
    "deepseek": {
      "baseUrl": "https://openrouter.ai/api/v1",
      "auth": "api-key",
      "api": "openai-completions",
      "apiKey": {
        "source": "file",
        "provider": "openrouter",
        "id": "value"
      },
      "models": [
        {
          "id": "deepseek/deepseek-v4-pro",
          "api": "openai-completions",
          "input": ["text"],
          "contextWindow": 128000
        }
      ]
    }
  }
}

With that alias, openclaw agent ... --json succeeds, but runtime metadata reports provider=deepseek, proving the workaround is absorbing the reparsed provider rather than preserving the intended openrouter provider.

Suspected source

There are multiple first-slash model ref parsers/normalizers. The risky pattern is splitting provider/model at the first slash without preserving that OpenRouter model ids themselves contain provider namespaces.

Relevant installed bundle references from 2026.5.12-beta.1:

  • dist/model-input-B9p-bobB.js: normalizeAgentModelRefForConfig() splits at the first slash.
  • dist/model-runtime-8a_1ShBR.js: normalizeModelRef(rawModel, fallbackProvider, parseEmbeddedProvider) reparses embedded provider when runtimeProvider is absent.
  • persisted session rows can contain modelProvider/model combinations that later select deepseek as provider.

Suggested fix

Model references need a representation that keeps provider id separate from provider-native model id. For OpenRouter and similar providers, provider=openrouter plus model=deepseek/deepseek-v4-pro must not be reparsed into provider=deepseek in later runtime/session paths.

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…

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 - 💡(How to fix) Fix `openclaw doctor --fix` / runtime model routing breaks OpenRouter nested model ids like `openrouter/deepseek/deepseek-v4-pro`