openclaw - 💡(How to fix) Fix [Bug]: sessions_spawn model parameter ignored due to write/read field mismatch [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#73811Fetched 2026-04-29 06:14:49
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
0
Author
Timeline (top)
closed ×1commented ×1

When sessions_spawn is called with an explicit model parameter (e.g., "ollama/kimi-k2.6:cloud"), the subagent ignores the parameter and uses the agent's default model instead. The spawn-supplied model never reaches the inference path.

This is caused by a field-name mismatch: the spawn writer populates entry.model and entry.modelProvider, but the agent-command handler reads from entry.modelOverride and entry.providerOverride. The handler's override-detection check returns false, and the spawn falls through to the agent's default model.

Error Message

This bug causes silent model substitution. The user requests one model, the system returns output from a different model, and there is no error or warning. For workflows that depend on specific models for quality, cost, or compliance reasons (e.g., routing writing tasks to a thinking-mode model while general chat uses a faster model), this produces unpredictable results that are difficult to diagnose without source-level investigation.

Root Cause

This bug causes silent model substitution. The user requests one model, the system returns output from a different model, and there is no error or warning. For workflows that depend on specific models for quality, cost, or compliance reasons (e.g., routing writing tasks to a thinking-mode model while general chat uses a faster model), this produces unpredictable results that are difficult to diagnose without source-level investigation.

Fix Action

Fix / Workaround

Writer — dist/subagent-spawn--QfZonyO.js lines 339-345 (function buildDirectChildSessionPatch):

if (typeof patch.model === "string" && patch.model.trim()) {
    const { provider, model } = splitModelRef(patch.model.trim());
    if (model) {
        entry.model = model;
        if (provider) entry.modelProvider = provider;
    }
}

Modified buildDirectChildSessionPatch to also write to modelOverride and providerOverride:

Code Example

if (typeof patch.model === "string" && patch.model.trim()) {
    const { provider, model } = splitModelRef(patch.model.trim());
    if (model) {
        entry.model = model;
        if (provider) entry.modelProvider = provider;
    }
}

---

const hasStoredOverride = Boolean(sessionEntry?.modelOverride || sessionEntry?.providerOverride);

---

--- a/dist/subagent-spawn--QfZonyO.js
+++ b/dist/subagent-spawn--QfZonyO.js
@@ -339,6 +339,8 @@ function buildDirectChildSessionPatch(patch) {
     if (typeof patch.model === "string" && patch.model.trim()) {
         const { provider, model } = splitModelRef(patch.model.trim());
         if (model) {
             entry.model = model;
+            entry.modelOverride = model;
             if (provider) entry.modelProvider = provider;
+            if (provider) entry.providerOverride = provider;
         }
     }
     return entry;
 }
RAW_BUFFERClick to expand / collapse

Description

When sessions_spawn is called with an explicit model parameter (e.g., "ollama/kimi-k2.6:cloud"), the subagent ignores the parameter and uses the agent's default model instead. The spawn-supplied model never reaches the inference path.

This is caused by a field-name mismatch: the spawn writer populates entry.model and entry.modelProvider, but the agent-command handler reads from entry.modelOverride and entry.providerOverride. The handler's override-detection check returns false, and the spawn falls through to the agent's default model.

Version

OpenClaw 2026.4.26 (be8c246) (also reproduces in 2026.4.25)

Source locations

Writer — dist/subagent-spawn--QfZonyO.js lines 339-345 (function buildDirectChildSessionPatch):

if (typeof patch.model === "string" && patch.model.trim()) {
    const { provider, model } = splitModelRef(patch.model.trim());
    if (model) {
        entry.model = model;
        if (provider) entry.modelProvider = provider;
    }
}

Reader — dist/agent-command-BxeGYLZy.js line 511:

const hasStoredOverride = Boolean(sessionEntry?.modelOverride || sessionEntry?.providerOverride);

Subsequent reads at lines 536-537 and 559-560 only consult modelOverride and providerOverride. Since the writer never populates those fields, hasStoredOverride evaluates to false and the override path is skipped entirely.

Reproduction

  1. Configure an agent with a primary model that differs from a model defined in models.providers.ollama.models (e.g., primary = minimax-portal/MiniMax-M2.7-highspeed, also configure kimi-k2.6:cloud under the ollama provider).
  2. Call sessions_spawn with model="ollama/kimi-k2.6:cloud" and any prompt.
  3. Inspect the subagent session JSONL for the model_change event.

Expected: provider: "ollama", modelId: "kimi-k2.6:cloud" Actual: provider: "minimax-portal", modelId: "MiniMax-M2.7-highspeed" (the agent default)

The session metadata also shows api: "anthropic-messages" instead of api: "ollama", confirming the request was served by the wrong provider.

Local fix that resolved it

Modified buildDirectChildSessionPatch to also write to modelOverride and providerOverride:

--- a/dist/subagent-spawn--QfZonyO.js
+++ b/dist/subagent-spawn--QfZonyO.js
@@ -339,6 +339,8 @@ function buildDirectChildSessionPatch(patch) {
     if (typeof patch.model === "string" && patch.model.trim()) {
         const { provider, model } = splitModelRef(patch.model.trim());
         if (model) {
             entry.model = model;
+            entry.modelOverride = model;
             if (provider) entry.modelProvider = provider;
+            if (provider) entry.providerOverride = provider;
         }
     }
     return entry;
 }

After this change, sessions_spawn with model="ollama/kimi-k2.6:cloud" correctly routes to the Ollama provider. Verified via subagent session metadata showing api=ollama, provider=ollama, model=kimi-k2.6:cloud.

Suggested upstream fix

Align the field names. Either standardize on modelOverride/providerOverride as the canonical fields and have buildDirectChildSessionPatch write to those exclusively, or have the agent-command handler check both model/modelProvider and modelOverride/providerOverride as fallbacks.

Why this matters

This bug causes silent model substitution. The user requests one model, the system returns output from a different model, and there is no error or warning. For workflows that depend on specific models for quality, cost, or compliance reasons (e.g., routing writing tasks to a thinking-mode model while general chat uses a faster model), this produces unpredictable results that are difficult to diagnose without source-level investigation.

extent analysis

TL;DR

The issue can be fixed by aligning the field names used by the spawn writer and the agent-command handler, either by standardizing on modelOverride and providerOverride or by having the handler check both sets of fields.

Guidance

  • Verify that the buildDirectChildSessionPatch function is correctly writing to modelOverride and providerOverride fields.
  • Check the agent-command handler to ensure it is reading from the correct fields (modelOverride and providerOverride).
  • Consider standardizing on a single set of fields to avoid similar issues in the future.
  • Test the fix by calling sessions_spawn with an explicit model parameter and verifying that the correct model is used.

Example

The provided diff shows the modification to buildDirectChildSessionPatch to write to modelOverride and providerOverride:

if (typeof patch.model === "string" && patch.model.trim()) {
    const { provider, model } = splitModelRef(patch.model.trim());
    if (model) {
        entry.model = model;
        entry.modelOverride = model;
        if (provider) entry.modelProvider = provider;
        if (provider) entry.providerOverride = provider;
    }
}

Notes

This fix assumes that the issue is solely due to the field-name mismatch and that there are no other factors at play.

Recommendation

Apply the suggested upstream fix to standardize on modelOverride and providerOverride as the canonical fields, and have buildDirectChildSessionPatch write to those exclusively. This will ensure consistency and avoid similar issues 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…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING