openclaw - ✅(Solved) Fix [Bug]: agents.list[].model.primary ignored - agents.defaults.subagents.model always wins [1 pull requests, 1 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#57993Fetched 2026-04-08 01:55:10
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Author
Participants
Timeline (top)
closed ×1cross-referenced ×1locked ×1

When a named agent is defined in agents.list[] with model.primary set (e.g., anthropic/claude-opus-4-6), and agents.defaults.subagents.model is also set (e.g., anthropic/claude-sonnet-4-6), the per-agent model config is ignored. The subagent always uses agents.defaults.subagents.model instead of its own model.primary.

Root Cause

When a named agent is defined in agents.list[] with model.primary set (e.g., anthropic/claude-opus-4-6), and agents.defaults.subagents.model is also set (e.g., anthropic/claude-sonnet-4-6), the per-agent model config is ignored. The subagent always uses agents.defaults.subagents.model instead of its own model.primary.

Fix Action

Fix / Workaround

agents.defaults.subagents.model always overrides agents.list[].model.primary. The only workaround is to pass an explicit model parameter on every sessions_spawn call.

Low-Medium - workaround exists (explicit model param), but violates principle of least surprise and makes per-agent model config useless.

PR fix notes

PR #58003: Agents: fix subagent model precedence

Description (problem / solution / changelog)

Summary

  • Problem: sessions_spawn and related subagent model resolution preferred agents.defaults.subagents.model over a named agent's own model.primary, so per-agent model defaults were ignored.
  • Why it matters: named agents could not reliably keep their configured primary model for spawned subagents unless every spawn call repeated an explicit model override.
  • What changed: reordered subagent model precedence to prefer agents.list[].subagents.model, then agents.list[].model.primary, then agents.defaults.subagents.model, and mirrored that precedence in isolated cron model resolution.
  • What did NOT change (scope boundary): explicit spawn/job model overrides still win, and no broader agent/default model resolution behavior was changed.

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 #57993
  • Related #57993
  • This PR fixes a bug or regression

Root Cause / Regression History (if applicable)

  • Root cause: resolveSubagentConfiguredModelSelection in src/agents/model-selection.ts placed agents.defaults.subagents.model ahead of the target agent's own model, so the global subagent default masked the per-agent primary model.
  • Missing detection / guardrail: there was no regression test asserting that a named agent's model.primary beats the global subagent default when subagents.model is unset.
  • Prior context (git blame, prior PR, issue, or refactor if known): issue #57993 reported the precedence mismatch with a direct repro.
  • Why this regressed now: the precedence chain encoded the wrong specificity order.
  • If unknown, what was ruled out: N/A.

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/model-selection.test.ts, src/cron/isolated-agent.subagent-model.test.ts, and src/gateway/sessions-patch.test.ts
  • Scenario the test should lock in: named agent model.primary is used for subagents unless a more specific agents.list[].subagents.model or explicit runtime override is present.
  • Why this is the smallest reliable guardrail: it locks the precedence helper directly and covers the two mirrored runtime consumers that depended on the old order.
  • Existing test that already covers this (if any): src/gateway/sessions-patch.test.ts already covered adjacent allowlist behavior and was updated to stay aligned with the corrected precedence.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

  • Named agents now keep their own model.primary for spawned subagents when agents.list[].subagents.model is unset, even if agents.defaults.subagents.model is configured.
  • Isolated cron runs now apply the same precedence when targeting a named agent.

Diagram (if applicable)

Before:
subagent spawn -> global defaults.subagents.model -> agent model.primary ignored

After:
subagent spawn -> agent subagents.model (if set) -> else agent model.primary -> else global defaults.subagents.model

Security Impact (required)

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

Repro + Verification

Environment

  • OS: macOS 15 / Darwin 25.x
  • Runtime/container: local Node 22+ / pnpm workspace
  • Model/provider: config-driven subagent model selection
  • Integration/channel (if any): N/A
  • Relevant config (redacted): agents.defaults.subagents.model, agents.list[].model.primary, optional agents.list[].subagents.model

Steps

  1. Configure agents.defaults.subagents.model and a named agent with a different model.primary.
  2. Spawn a subagent for that named agent without an explicit model override.
  3. Inspect the resolved subagent model.

Expected

  • The named agent's model.primary is used unless agents.list[].subagents.model is configured.

Actual

  • Before this fix, agents.defaults.subagents.model won and masked the named agent's model.primary.

Evidence

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

Human Verification (required)

  • Verified scenarios: reproduced the precedence issue in code inspection, updated the precedence helper, ran targeted regression tests for model selection, cron isolated-agent subagent resolution, and gateway sessions patch behavior; also ran pnpm check and pnpm build.
  • Edge cases checked: agent subagents.model still outranks agent model.primary; explicit runtime/job model overrides still outrank config defaults; global defaults.subagents.model still applies when the agent has no explicit model.
  • What you did not verify: I did not change or validate unrelated CLI help output; repo-wide pnpm test still reports the existing unrelated failure in src/cli/config-cli.test.ts about --container examples in help text.

AI Assistance

  • AI-assisted: yes

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.

Compatibility / Migration

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

Risks and Mitigations

  • Risk: another runtime path could still encode a different subagent model precedence order.
    • Mitigation: the helper and isolated cron path now match, and regression tests cover both direct helper precedence and mirrored runtime usage.

Made with Cursor

Changed files

  • src/agents/model-selection.test.ts (modified, +46/-0)
  • src/agents/model-selection.ts (modified, +2/-2)
  • src/cron/isolated-agent.subagent-model.test.ts (modified, +25/-0)
  • src/cron/isolated-agent/model-selection.ts (modified, +2/-0)
  • src/gateway/sessions-patch.test.ts (modified, +2/-3)
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Summary

When a named agent is defined in agents.list[] with model.primary set (e.g., anthropic/claude-opus-4-6), and agents.defaults.subagents.model is also set (e.g., anthropic/claude-sonnet-4-6), the per-agent model config is ignored. The subagent always uses agents.defaults.subagents.model instead of its own model.primary.

Steps to reproduce

  1. Set agents.defaults.subagents.model: "anthropic/claude-sonnet-4-6" in openclaw.json
  2. Add a named agent to agents.list[] with model.primary: "anthropic/claude-opus-4-6"
  3. Spawn it via sessions_spawn(agentId: "research")
  4. Check subagents list - the session shows the defaults model, not the per-agent model

Expected behavior

Per-agent model.primary in agents.list[] should take precedence over agents.defaults.subagents.model. The more specific config should win.

Actual behavior

agents.defaults.subagents.model always overrides agents.list[].model.primary. The only workaround is to pass an explicit model parameter on every sessions_spawn call.

Evidence

Agent "research" configured with model.primary: "anthropic/claude-opus-4-6". When spawned without explicit model parameter, subagents list shows model: "anthropic/claude-sonnet-4-6" (the defaults value). Passing model: "anthropic/claude-opus-4-6" explicitly on sessions_spawn works correctly.

OpenClaw version

2026.3.28

Operating system

macOS 15 (Darwin 25.4.0, arm64, Apple M4 Ultra)

Install method

npm global install

Impact and severity

Low-Medium - workaround exists (explicit model param), but violates principle of least surprise and makes per-agent model config useless.

extent analysis

Fix Plan

To fix the issue, we need to modify the code to prioritize the per-agent model.primary configuration over the agents.defaults.subagents.model configuration.

Here are the steps:

  • Modify the sessions_spawn function to check for the model.primary configuration in the agent's settings before falling back to the default agents.defaults.subagents.model configuration.
  • Update the subagents list to reflect the correct model configuration.

Example code snippet:

// In sessions_spawn function
const agentConfig = getAgentConfig(agentId);
const model = agentConfig.model.primary || agents.defaults.subagents.model;
// Use the determined model configuration

// In getAgentConfig function
function getAgentConfig(agentId) {
  const agent = agents.list.find((agent) => agent.id === agentId);
  return agent || {};
}

Verification

To verify the fix, follow these steps:

  • Set agents.defaults.subagents.model to a default value (e.g., "anthropic/claude-sonnet-4-6").
  • Add a named agent to agents.list[] with model.primary set to a different value (e.g., "anthropic/claude-opus-4-6").
  • Spawn the agent using sessions_spawn without passing an explicit model parameter.
  • Check the subagents list to ensure it shows the per-agent model.primary configuration instead of the default agents.defaults.subagents.model configuration.

Extra Tips

  • Make sure to test the fix with different agent configurations to ensure it works as expected.
  • Consider adding a test case to cover this scenario to prevent regressions in the future.

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

Per-agent model.primary in agents.list[] should take precedence over agents.defaults.subagents.model. The more specific config should win.

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]: agents.list[].model.primary ignored - agents.defaults.subagents.model always wins [1 pull requests, 1 participants]