Skip to content

[Bug] Cron isolated jobs created from chat sessions may persist current sessionKey and lose true isolation #58083

@jrsdhr

Description

@jrsdhr

Summary

When creating a cron job from a Discord/chat session with sessionTarget: "isolated", OpenClaw appears to persist the current chat sessionKey onto the job even when sessionKey was not explicitly provided.

That makes the job run against the chat-bound session instead of the expected isolated cron:<jobId> session, which can leak session/model state into a background script-style cron and cause runtime failures such as LiveSessionModelSwitchError.

Expected behavior

For cron jobs with:

  • sessionTarget: "isolated"
  • no explicit sessionKey provided

OpenClaw should run the job in an isolated cron session (cron:<jobId>) and should not implicitly persist the creating chat/session sessionKey onto the job.

Actual behavior

Creating the cron job from a Discord session produced a stored job like this (abridged):

{
  "sessionTarget": "isolated",
  "payload": {
    "kind": "agentTurn",
    "model": "anthropic/claude-sonnet-4-6"
  },
  "sessionKey": "agent:cron-lite:discord:channel:1475102142951067682"
}

Because sessionKey is present, the isolated runner uses that session key instead of cron:<jobId>.

Why this seems wrong

From the runtime code path, isolated cron execution uses roughly:

const baseSessionKey = params.sessionKey?.trim() || `cron:${params.job.id}`;

So if a job gets a sessionKey injected during creation, it no longer behaves like a clean isolated cron run.

This is especially problematic for script-style jobs that:

  • do not need chat history
  • do not need current-session binding
  • use delivery.mode = "none"
  • are intended to run as clean background tasks

Observed failure mode

The affected job started failing with model-switch conflicts like:

LiveSessionModelSwitchError: Live session model switch requested: anthropic/claude-haiku-4-5

and earlier also:

LiveSessionModelSwitchError: Live session model switch requested: anthropic/claude-sonnet-4-6

This strongly suggests the cron run was inheriting/contending with model state from the chat-bound session.

Reproduction

  1. From a Discord/OpenClaw chat session, create a cron job using the cron tool/API with:
    • sessionTarget: "isolated"
    • payload.kind: "agentTurn"
    • no explicit sessionKey
  2. Inspect the stored/listed cron job.
  3. Observe that the job may contain the current chat sessionKey.
  4. Run the job and observe that it does not behave like a clean cron:<jobId> isolated session.

Workaround

Manually clearing the stored sessionKey fixes the issue:

{
  "patch": {
    "sessionKey": null
  }
}

After patching sessionKey to null, the job no longer shows the chat-bound session key and behaves as expected.

Additional notes

This does not look like a problem with the isolated cron execution core itself.
The likely issue seems to be in the cron creation/request path, where the creating session's sessionKey is being implicitly forwarded/persisted onto the job even for sessionTarget: "isolated" jobs.

That may be reasonable for sessionTarget: "current", but it seems incorrect for plain isolated jobs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    close:duplicateClosed as duplicatededupe:childDuplicate issue/PR child in dedupe cluster

    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