Bug
Cron jobs with payload.model set to a different model than the agent's primary model always fall back to the agent's primary model. The docs state that job payload override has highest priority, but the code disagrees.
Environment
- OpenClaw 2026.3.28 (f9b1079)
- Agent primary model:
anthropic/claude-opus-4-6
- Cron
payload.model: anthropic/claude-sonnet-4-6
- Sonnet is in
agents.defaults.models allowlist
Steps to reproduce
- Configure an agent with
anthropic/claude-opus-4-6 as primary model
- Add
anthropic/claude-sonnet-4-6 to agents.defaults.models allowlist
- Create an isolated cron job with
payload.model: "anthropic/claude-sonnet-4-6"
- Run the cron job (
openclaw cron run <id>)
- Check run history — model shows
claude-opus-4-6, not Sonnet
Observed behavior
Gateway logs show:
[agent/embedded] live session model switch detected before attempt for <runId>: anthropic/claude-sonnet-4-6 -> anthropic/claude-opus-4-6
[model-fallback/decision] candidate_failed, requestedModel: claude-sonnet-4-6, errorPreview: "Live session model switch requested: anthropic/claude-opus-4-6"
[model-fallback/decision] candidate_succeeded, candidateModel: claude-opus-4-6, attempt: 2
The cron correctly starts with Sonnet, but then a "live session model switch" overrides it to the agent's primary model (Opus). Sonnet is treated as a failed candidate, and Opus succeeds as fallback.
Expected behavior
Per cron-jobs.md:
Resolution priority:
- Job payload override (highest)
- Hook-specific defaults
- Agent config default
payload.model should take precedence over the agent's primary model for isolated cron jobs.
Additional context
- Tested with
agentId: "main" and with --clear-agent — same result both ways
- Session key is always
agent:main:cron:... even without explicit agentId
- The
agents.defaults.models allowlist is not the issue (no "not allowed" warning after adding Sonnet)
- The "not allowed" issue from earlier versions (2026.3.24) is separate and was fixed by adding Sonnet to the allowlist
Bug
Cron jobs with
payload.modelset to a different model than the agent's primary model always fall back to the agent's primary model. The docs state that job payload override has highest priority, but the code disagrees.Environment
anthropic/claude-opus-4-6payload.model:anthropic/claude-sonnet-4-6agents.defaults.modelsallowlistSteps to reproduce
anthropic/claude-opus-4-6as primary modelanthropic/claude-sonnet-4-6toagents.defaults.modelsallowlistpayload.model: "anthropic/claude-sonnet-4-6"openclaw cron run <id>)claude-opus-4-6, not SonnetObserved behavior
Gateway logs show:
The cron correctly starts with Sonnet, but then a "live session model switch" overrides it to the agent's primary model (Opus). Sonnet is treated as a failed candidate, and Opus succeeds as fallback.
Expected behavior
Per cron-jobs.md:
payload.modelshould take precedence over the agent's primary model for isolated cron jobs.Additional context
agentId: "main"and with--clear-agent— same result both waysagent:main:cron:...even without explicit agentIdagents.defaults.modelsallowlist is not the issue (no "not allowed" warning after adding Sonnet)