openclaw - ✅(Solved) Fix [Bug]: models.json baseUrl automatically appends "/v1" on restart [1 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#67875Fetched 2026-04-17 08:29:10
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Author
Timeline (top)
labeled ×2closed ×1commented ×1cross-referenced ×1

When editing the models.json file to set provider baseUrls without the "/v1" suffix, the baseUrl automatically gets "/v1" appended after restarting the OpenClaw gateway.

Root Cause

When editing the models.json file to set provider baseUrls without the "/v1" suffix, the baseUrl automatically gets "/v1" appended after restarting the OpenClaw gateway.

Fix Action

Fixed

PR fix notes

PR #67893: [AI-assisted] fix(models-config): preserve existing models.json baseUrls on regen

Description (problem / solution / changelog)

Summary

  • Problem: restarting the gateway rewrites a non-empty agent models.json baseUrl back to the config/provider value, so custom endpoints like https://api.kilo.ai/api/gateway get forced back to /v1.
  • Why it matters: merge mode is documented to preserve an existing agent models.json baseUrl, and users editing custom provider endpoints lose those changes on restart.
  • What changed: removed the merge special-case that let explicit config baseUrl values override non-empty agent models.json baseUrl values; added regression tests at the merge, plan, and runtime-snapshot layers.
  • What did NOT change (scope boundary): models.mode: "replace" behavior is unchanged, and stale baseUrl values still refresh when the provider API surface changes.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #67875
  • Related #67875
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the recent models.json merge refactor added an explicitBaseUrlProviders override in src/agents/models-config.merge.ts, which forced config models.providers.*.baseUrl to win even in merge mode.
  • Missing detection / guardrail: merge tests encoded the wrong precedence, and there was no plan-level regression test covering a restart rewrite from an existing models.json file.
  • Contributing context (if known): the documented merge semantics in docs/concepts/models.md and docs/gateway/configuration-reference.md already say that a non-empty agent models.json baseUrl should win.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/agents/models-config.uses-first-github-copilot-profile-env-tokens.test.ts
    • src/agents/models-config.merge.test.ts
    • src/agents/models-config.runtime-source-snapshot.test.ts
  • Scenario the test should lock in: when merge mode regenerates models.json, an existing non-empty agent baseUrl survives restart/regeneration unless the provider API surface changed.
  • Why this is the smallest reliable guardrail: the bug is in the merge/planning path, so these tests exercise the exact persistence behavior without requiring a full gateway boot.
  • Existing test that already covers this (if any): none.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

  • In merge mode, custom provider baseUrl values already present in ~/.openclaw/agents/<agentId>/agent/models.json now survive gateway regeneration/restart again.

Diagram (if applicable)

Before:
[user edits models.json baseUrl] -> [gateway restart] -> [config baseUrl overwrites existing value]

After:
[user edits models.json baseUrl] -> [gateway restart] -> [existing models.json baseUrl preserved] -> [custom endpoint remains usable]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS 15.x
  • Runtime/container: Node 24.14.0 via nvm
  • Model/provider: custom OpenAI-compatible provider config (kilocode repro)
  • Integration/channel (if any): none
  • Relevant config (redacted): models.mode: "merge", models.providers.kilocode.baseUrl: "https://api.kilo.ai/api/gateway/v1"

Steps

  1. Start with merge mode and a configured custom provider whose config baseUrl ends in /v1.
  2. Write an existing agent models.json entry for the same provider with a non-empty baseUrl that omits /v1.
  3. Regenerate models.json via the normal planning path (or restart the gateway).

Expected

  • The existing agent models.json baseUrl stays unchanged in merge mode.

Actual

  • Before this fix, regeneration rewrote the agent baseUrl back to the config value with /v1.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: reproduced the rewrite locally with mergeWithExistingProviderSecrets and planOpenClawModelsJsonWithDeps, then verified the updated tests and commit hook preserve the existing baseUrl while still refreshing other fields.
  • Edge cases checked: stale baseUrl values still refresh when the provider API surface changes; runtime-source-snapshot regeneration still updates refreshable headers under the same snapshot.
  • What you did not verify: I did not run an actual Android/Termux gateway restart or Kilo Code end-to-end integration.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: users who relied on merge mode to force config baseUrl updates into an existing agent models.json will now keep the existing value instead.
    • Mitigation: this restores the documented merge precedence; models.mode: "replace" and API-surface mismatch handling still provide the explicit overwrite paths.

AI Assistance

  • AI-assisted: Codex
  • Testing note: fully tested for the touched surface (build, targeted test, full pre-commit check)
  • Prompt/session summary: fix the regression where merge mode rewrites a non-empty agent models.json baseUrl back to the config value on restart, with concrete repro, minimal scope, and regression coverage.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/models-config.merge.test.ts (modified, +5/-13)
  • src/agents/models-config.merge.ts (modified, +3/-13)
  • src/agents/models-config.plan.ts (modified, +0/-17)
  • src/agents/models-config.runtime-source-snapshot.test.ts (modified, +18/-3)
  • src/agents/models-config.uses-first-github-copilot-profile-env-tokens.test.ts (modified, +49/-0)

Code Example

<img width="1271" height="1676" alt="Image" src="https://github.com/user-attachments/assets/e4aaa490-3e5c-45c3-aa18-c5a5918e4edf" />
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

When editing the models.json file to set provider baseUrls without the "/v1" suffix, the baseUrl automatically gets "/v1" appended after restarting the OpenClaw gateway.

Steps to reproduce

  1. Edit ~/.openclaw/agents/main/agent/models.json to set baseUrl without "/v1":"kilocode": { "baseUrl": "https://api.kilo.ai/api/gateway" }
  2. Run pkill -9 -f openclaw && openclaw gateway
  3. Check models.json - baseUrl has changed to https://api.kilo.ai/api/gateway/v1

Expected behavior

The baseUrl should remain as configured by the user (https://api.kilo.ai/api/gateway).

Actual behavior

baseUrl gets "/v1" appended automatically (https://api.kilo.ai/api/gateway/v1).

OpenClaw version

2026.4.15

Operating system

Android (Termux)

Install method

No response

Model

kilocode: https://api.kilo.ai/api/gatewayhttps://api.kilo.ai/api/gateway/v1

Provider / routing chain

openclaw→cloudflare-ai-gateway→kilocode

Additional provider/model setup details

No response

Logs, screenshots, and evidence

<img width="1271" height="1676" alt="Image" src="https://github.com/user-attachments/assets/e4aaa490-3e5c-45c3-aa18-c5a5918e4edf" />

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

The baseUrl in the models.json file is being automatically appended with "/v1" after restarting the OpenClaw gateway, which can be mitigated by modifying the configuration or startup process.

Guidance

  • Verify that the OpenClaw gateway is correctly configured to respect user-provided baseUrls without modification.
  • Check the OpenClaw documentation for any specific settings or environment variables that control baseUrl formatting.
  • Consider modifying the startup script or configuration to prevent automatic appending of "/v1" to the baseUrl.
  • Test the behavior with different baseUrl formats to determine if the issue is specific to the "kilocode" model or a more general problem.

Example

No code snippet is provided as the issue is related to configuration and not code.

Notes

The issue may be specific to the OpenClaw version (2026.4.15) or the Android (Termux) operating system, and further testing on different environments may be necessary to determine the root cause.

Recommendation

Apply workaround: Modify the startup script or configuration to prevent automatic appending of "/v1" to the baseUrl, as the root cause of the issue is unclear and may require further investigation.

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

The baseUrl should remain as configured by the user (https://api.kilo.ai/api/gateway).

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 [Bug]: models.json baseUrl automatically appends "/v1" on restart [1 pull requests, 1 comments, 2 participants]