Skip to content

sessions.patch model override not applied to spawned sub-agents #5369

@tobiasheim

Description

@tobiasheim

Summary

When spawning sub-agents via sessions_spawn, the model parameter (whether from config agents.defaults.subagents.model or passed explicitly) is not being applied. The sub-agent runs on the main session model instead.

Steps to Reproduce

  1. Set agents.defaults.subagents.model to a different model than the main session:

    {
      "agents": {
        "defaults": {
          "subagents": {
            "model": "anthropic/claude-sonnet-4"
          }
        }
      }
    }
  2. Spawn a sub-agent:

    sessions_spawn({
      task: "What model are you running as?",
      label: "model-test"
    })
  3. Or spawn with explicit model parameter:

    sessions_spawn({
      task: "What model are you running as?",
      model: "anthropic/claude-sonnet-4"
    })

Expected Behavior

  • Sub-agent should run on anthropic/claude-sonnet-4
  • modelApplied: true in spawn response should mean the model was actually applied

Actual Behavior

  • Sub-agent runs on main session model (anthropic/claude-opus-4-5)
  • modelApplied: true is returned (misleading)
  • Session store entries show model and modelProvider fields but no modelOverride/providerOverride fields

Investigation Findings

Traced through the code:

  1. sessions-spawn-tool.js correctly reads the config and calls sessions.patch:

    const resolvedModel = normalizeModelSelection(modelOverride) ??
        normalizeModelSelection(targetAgentConfig?.subagents?.model) ??
        normalizeModelSelection(cfg.agents?.defaults?.subagents?.model);
    
    await callGateway({
        method: "sessions.patch",
        params: { key: childSessionKey, model: resolvedModel },
    });
  2. sessions-patch.js calls applyModelOverrideToSessionEntry which should set providerOverride and modelOverride on the session entry

  3. Gateway agent method reads the entry and passes it through, including modelOverride: entry?.modelOverride

  4. agentCommand calls resolveSession which loads the store again, and model selection code checks for sessionEntry.modelOverride

  5. updateSessionStoreAfterAgentRun writes model and modelProvider (the actually-used model) back to the store, but the override should have been applied before the run

Possible Root Causes

  • applyModelOverrideToSessionEntry may not be writing the override correctly for new sessions
  • The override may be lost between sessions.patch completing and the agent method reading the entry (timing/caching?)
  • agentCommand model selection may not be finding the override due to key mismatch or store path differences

Environment

  • OpenClaw version: 2026.1.29
  • Node: v24.13.0 / v25.4.0
  • OS: macOS (Darwin arm64)

Workaround

None known - sub-agents always use the main session model regardless of config or explicit parameter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstaleMarked as stale due to inactivity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions