-
-
Notifications
You must be signed in to change notification settings - Fork 52.6k
Description
Summary
Bug Report: Agent-level models.json apiKey not overriding main config
Environment
- OpenClaw Version: (installed globally via npm)
- Node Version: v24.13.0
- Platform: Linux (deployed on server 10.10.164.9)
Description
When using agent-level models.json files to customize provider configurations (specifically apiKey and baseUrl), the values are not being applied correctly. The model name is correctly overridden, but the apiKey and baseUrl from the main openclaw.json configuration take precedence instead of the agent-specific values.
Steps to Reproduce
-
Create an agent-specific models.json file at:
~/.openclaw/agents/{agentId}/agent/models.jsonWith content:
{ "providers": { "user-custom": { "baseUrl": "https://custom-api.example.com/", "apiKey": "agent_specific_key_12345", "models": [ { "id": "claude-4-sonnet", "name": "Claude 4 Sonnet" } ] } } } -
In main
~/.openclaw/openclaw.json, configure the agent:{ "agents": { "list": [ { "id": "test-agent", "model": "user-custom/claude-4-sonnet" } ] }, "models": { "providers": { "user-custom": { "baseUrl": "https://main-api.example.com/", "apiKey": "main_config_key_67890", "models": [] } } } } -
Start a new session with the agent and observe which API key is used
Expected Behavior
The agent should use:
- ✅ Model name:
user-custom/claude-4-sonnet(from agent models.json) - ✅ API Key:
agent_specific_key_12345(from agent models.json) - ✅ Base URL:
https://custom-api.example.com/(from agent models.json)
Actual Behavior
The agent uses:
- ✅ Model name:
user-custom/claude-4-sonnet(correctly from agent models.json) - ❌ API Key:
main_config_key_67890(incorrectly from main config) - ❌ Base URL:
https://main-api.example.com/(incorrectly from main config)
Root Cause Analysis
After examining the source code in dist/image-D9rvznlL.js, the issue is in the mergeProviderModels function (lines 17-42):
function mergeProviderModels(implicit, explicit) {
const implicitModels = Array.isArray(implicit.models) ? implicit.models : [];
const explicitModels = Array.isArray(explicit.models) ? explicit.models : [];
if (implicitModels.length === 0) return {
...implicit,
...explicit
};
// ... model merging logic ...
return {
...implicit, // agent models.json
...explicit, // main config - THIS OVERWRITES implicit!
models: mergedModels
};
}Problem: The spread operator order {...implicit, ...explicit} causes the explicit (main config) properties to overwrite the implicit (agent models.json) properties, including apiKey and baseUrl.
Expected behavior: Agent-level configuration should have higher priority than main config for per-agent customization.
Suggested Fix
Change the spread operator order in the return statement:
return {
...explicit, // main config as defaults
...implicit, // agent config overrides
models: mergedModels
};Or, to be more explicit and avoid unintended overwrites:
return {
baseUrl: implicit.baseUrl ?? explicit.baseUrl,
apiKey: implicit.apiKey ?? explicit.apiKey,
// ... other properties with explicit precedence
models: mergedModels
};Workaround
Currently, the only workaround is to define separate providers for each agent directly in the main openclaw.json:
{
"models": {
"providers": {
"user-agent1": {
"apiKey": "key_for_agent1",
"models": [...]
},
"user-agent2": {
"apiKey": "key_for_agent2",
"models": [...]
}
}
}
}However, this defeats the purpose of agent-level models.json files and makes multi-agent configuration management difficult.
Impact
This bug affects:
- Multi-agent setups where different agents need different API keys
- Per-agent customization of baseUrl (e.g., using different API gateways)
- Any scenario requiring agent-specific provider configuration
Additional Context
- The
modelsarray merging works correctly (models are properly combined) - Only provider properties like
apiKey,baseUrl, etc. are affected - The agent-level
models.jsonfile is being loaded (evidenced by model names working) - The configuration merging logic appears to have the precedence backwards
Steps to reproduce
above
Expected behavior
above
Actual behavior
above
OpenClaw version
2026.2.9
Operating system
linux
Install method
npm global
Logs, screenshots, and evidence
Impact and severity
No response
Additional information
No response