Summary
When a cron job with sessionTarget: "current" fires, it runs in the bound chat session as expected — but the next user message to that session triggers a silent session reset, losing all conversation context (including the cron output).
Environment
- OpenClaw: 2026.5.7 (eeef486)
- Node: v22.22.0
- OS: Linux 6.8.0-110-generic (x64)
- Session reset config:
mode: "idle", idleMinutes: 5256000 (effectively disabled)
Steps to Reproduce
- Start a conversation with the agent (e.g., via Telegram DM)
- During the conversation, create a cron job with
sessionTarget: "current" and payload.kind: "agentTurn", scheduled to fire in a few minutes
- Wait for the cron job to fire — the agent responds in the session, context is preserved ✅
- Send a new message from the user
- Bug: the session is silently reset —
sessionId changes, transcript file changes, messages=0, historyTextChars=0. The agent has no memory of anything discussed before.
What Happens Internally
Job creation
The sessionTarget: "current" is correctly resolved at creation time to "session:agent:main:direct:<peerId>" in normalizeCronJobInput() (openclaw-tools-*.js). The sessionKey is set to the active chat session key.
Cron fires
The cron runtime calls resolveCronSession() with forceNew: false (because this is a "session:..." target, not "isolated"). It reuses the existing session entry and sessionId. The agent run executes with full conversation context — this part works correctly.
Evidence from logs (timestamps in UTC+7):
20:23:22 cron run starts: sessionId=41cf57ff, messages=16, sessionFile=41cf57ff...jsonl
20:23:29 cron run completes successfully, result delivered
User sends next message — session reset
20:25:21 preflightCompaction check: persistedFresh=false
20:25:21 new sessionId=a56142d8 created
20:25:23 context-diag: messages=0, historyTextChars=0, sessionFile=a56142d8...jsonl
No explicit "reset" or "rollover" log entry exists between these events. The session is silently recreated.
Key observation
The preflightCompaction check shows persistedFresh=false, meaning the session entry loaded from storage is already considered stale when the user message arrives — even though idle timeout is set to ~10 years.
Root Cause (Hypothesis)
When the cron run completes, it writes updated session entry metadata back to the store. This update likely changes fields (updatedAt, sessionId, sessionFile, systemSent, or other runtime state) in a way that causes the channel message handler's freshness check to fail on the next user message.
The most likely mechanism: the cron run modifies the session entry in a way that is incompatible with how the channel handler evaluates session freshness. Since resolveCronSession() uses resetType: "direct" and the channel handler also uses "direct", but they may interpret the entry state differently after the cron write.
Expected Behavior
After a sessionTarget: "current" cron job fires and completes, the next user message should continue in the same session with full conversation history intact — the cron output should be visible in the transcript.
Actual Behavior
The next user message creates a brand new session (new sessionId, new transcript file, zero history). All prior context is lost.
Workaround
Use sessionTarget: "isolated" with delivery: { mode: "announce" } instead. This runs in a separate session and delivers the result via chat — but the agent in the main session won't see the cron output in its own context.
For cases where the agent needs to self-follow-up (e.g., "check if a download completed"), the recommended pattern is to use background exec processes and check via process tool, avoiding cron entirely.
Impact
sessionTarget: "current" is essentially unusable in its current state — any cron job with this target will cause a session wipe on the next user interaction. This defeats the purpose of binding to the current session for context-aware follow-ups.
Summary
When a cron job with
sessionTarget: "current"fires, it runs in the bound chat session as expected — but the next user message to that session triggers a silent session reset, losing all conversation context (including the cron output).Environment
mode: "idle",idleMinutes: 5256000(effectively disabled)Steps to Reproduce
sessionTarget: "current"andpayload.kind: "agentTurn", scheduled to fire in a few minutessessionIdchanges, transcript file changes,messages=0,historyTextChars=0. The agent has no memory of anything discussed before.What Happens Internally
Job creation
The
sessionTarget: "current"is correctly resolved at creation time to"session:agent:main:direct:<peerId>"innormalizeCronJobInput()(openclaw-tools-*.js). ThesessionKeyis set to the active chat session key.Cron fires
The cron runtime calls
resolveCronSession()withforceNew: false(because this is a"session:..."target, not"isolated"). It reuses the existing session entry andsessionId. The agent run executes with full conversation context — this part works correctly.Evidence from logs (timestamps in UTC+7):
User sends next message — session reset
No explicit "reset" or "rollover" log entry exists between these events. The session is silently recreated.
Key observation
The
preflightCompactioncheck showspersistedFresh=false, meaning the session entry loaded from storage is already considered stale when the user message arrives — even though idle timeout is set to ~10 years.Root Cause (Hypothesis)
When the cron run completes, it writes updated session entry metadata back to the store. This update likely changes fields (
updatedAt,sessionId,sessionFile,systemSent, or other runtime state) in a way that causes the channel message handler's freshness check to fail on the next user message.The most likely mechanism: the cron run modifies the session entry in a way that is incompatible with how the channel handler evaluates session freshness. Since
resolveCronSession()usesresetType: "direct"and the channel handler also uses"direct", but they may interpret the entry state differently after the cron write.Expected Behavior
After a
sessionTarget: "current"cron job fires and completes, the next user message should continue in the same session with full conversation history intact — the cron output should be visible in the transcript.Actual Behavior
The next user message creates a brand new session (new
sessionId, new transcript file, zero history). All prior context is lost.Workaround
Use
sessionTarget: "isolated"withdelivery: { mode: "announce" }instead. This runs in a separate session and delivers the result via chat — but the agent in the main session won't see the cron output in its own context.For cases where the agent needs to self-follow-up (e.g., "check if a download completed"), the recommended pattern is to use background
execprocesses and check viaprocesstool, avoiding cron entirely.Impact
sessionTarget: "current"is essentially unusable in its current state — any cron job with this target will cause a session wipe on the next user interaction. This defeats the purpose of binding to the current session for context-aware follow-ups.