Summary
Passing a fully-qualified --model <provider>/<model> to openclaw agent is rejected as not-allowed when that model has an alias whose value looks similar to the model id stem. The validator appears to substitute the alias into the model field during normalization, then checks the alias-substituted form against the agent's visibility allowlist — which only contains the canonical model id — and fails.
Repro
Config (~/.openclaw/openclaw.json, abbreviated):
{
"agents": {
"defaults": {
"model": { "primary": "openai-codex/gpt-5.5", "fallbacks": ["claude-cli/claude-opus-4-7"] },
"models": {
"openai-codex/gpt-5.5": {
"alias": "gpt5",
"agentRuntime": { "id": "codex" }
}
}
},
"list": [{ "id": "main", "default": true, "subagents": { "allowAgents": [...] } }]
}
}
Then:
openclaw agent --agent main \
--message "ping" \
--model openai-codex/gpt-5.5 \
--thinking low --timeout 60 --json
Expected
Gateway accepts the explicit override (the model is in the configured catalog) and runs the agent on openai-codex/gpt-5.5.
Actual
GatewayClientRequestError: Error: Model override "openai-codex/gpt5" is not allowed for agent "main".
Note the model name in the error: openai-codex/gpt5 — the canonical gpt-5.5 has been substituted with the alias gpt5. That alias-form key is not on the agent's allowlist (the allowlist holds the canonical openai-codex/gpt-5.5), so validation rejects.
Suspected location
dist/agent-command-DnlmbHdz.js ~line 595-598 (the explicit override branch):
const explicitRef = explicitModelOverride
? explicitProviderOverride
? normalizeModelRef(explicitProviderOverride, explicitModelOverride)
: parseModelRef(explicitModelOverride, provider)
: explicitProviderOverride
? normalizeModelRef(explicitProviderOverride, model)
: null;
if (!explicitRef) throw new Error("Invalid model override.");
const explicitKey = modelKey(explicitRef.provider, explicitRef.model);
if (!visibilityPolicy.allowsKey(explicitKey))
throw new Error(`Model override "${...}/${...}" is not allowed for agent "${sessionAgentId}".`);
parseModelRef / normalizeModelRef evidently substitutes a model's alias into the .model field rather than resolving aliases the other direction (alias → canonical id). The visibility allowlist holds canonical ids, so the comparison can never match.
Direction of alias resolution looks inverted: when the input is already a canonical provider/model pair, the normalizer should leave it alone (or resolve any alias back to the canonical id) before allowlist check.
Workaround
Rename the colliding alias. In our case, renaming openai-codex/gpt-5.5's alias from gpt5 → gpt55 makes the validator stop substituting and accept the override. Hot-reload picks the change up.
Impact
Any caller passing a fully-qualified --model for a model that happens to have an alias breaks. Hit in production via internal codex CLI smoke harness running:
openclaw agent --agent main --session-id <s> --model openai-codex/gpt-5.5 --message ...
Repro on openclaw 2026.5.14-beta.2 (e029c12).
Environment
- OpenClaw 2026.5.14-beta.2 (e029c12)
- macOS 26.x ARM (FreeSWITCH gateway runs separately on Linux but unrelated)
- Codex CLI 0.130.0 (Homebrew cask)
Summary
Passing a fully-qualified
--model <provider>/<model>toopenclaw agentis rejected as not-allowed when that model has analiaswhose value looks similar to the model id stem. The validator appears to substitute the alias into the model field during normalization, then checks the alias-substituted form against the agent's visibility allowlist — which only contains the canonical model id — and fails.Repro
Config (
~/.openclaw/openclaw.json, abbreviated):{ "agents": { "defaults": { "model": { "primary": "openai-codex/gpt-5.5", "fallbacks": ["claude-cli/claude-opus-4-7"] }, "models": { "openai-codex/gpt-5.5": { "alias": "gpt5", "agentRuntime": { "id": "codex" } } } }, "list": [{ "id": "main", "default": true, "subagents": { "allowAgents": [...] } }] } }Then:
openclaw agent --agent main \ --message "ping" \ --model openai-codex/gpt-5.5 \ --thinking low --timeout 60 --jsonExpected
Gateway accepts the explicit override (the model is in the configured catalog) and runs the agent on
openai-codex/gpt-5.5.Actual
Note the model name in the error:
openai-codex/gpt5— the canonicalgpt-5.5has been substituted with the aliasgpt5. That alias-form key is not on the agent's allowlist (the allowlist holds the canonicalopenai-codex/gpt-5.5), so validation rejects.Suspected location
dist/agent-command-DnlmbHdz.js~line 595-598 (the explicit override branch):parseModelRef/normalizeModelRefevidently substitutes a model's alias into the.modelfield rather than resolving aliases the other direction (alias → canonical id). The visibility allowlist holds canonical ids, so the comparison can never match.Direction of alias resolution looks inverted: when the input is already a canonical
provider/modelpair, the normalizer should leave it alone (or resolve any alias back to the canonical id) before allowlist check.Workaround
Rename the colliding alias. In our case, renaming
openai-codex/gpt-5.5's alias fromgpt5→gpt55makes the validator stop substituting and accept the override. Hot-reload picks the change up.Impact
Any caller passing a fully-qualified
--modelfor a model that happens to have an alias breaks. Hit in production via internal codex CLI smoke harness running:Repro on
openclaw 2026.5.14-beta.2 (e029c12).Environment