Skip to content

Isolated cron jobs with explicit sessionKey overwrite parent session's updatedAt, preventing daily reset #51000

Description

@daniel-knox

Bug

Isolated cron jobs (sessionTarget: "isolated") that specify a sessionKey matching the main session key (e.g., agent:main:main) overwrite the parent session entry in the session store, including updatedAt. This prevents the daily session reset from triggering.

Root Cause

In src/cron/isolated-agent/session.ts, persistSessionEntry does a raw write:

store[agentSessionKey] = cronSession.sessionEntry;

When agentSessionKey resolves to the same key as the main session (e.g., agent:main:main), the cron run's session entry replaces the main session's entry entirely — including updatedAt, sessionId, model, and all other fields.

Impact

evaluateSessionFreshness checks updatedAt < dailyResetAtMs to determine staleness. When an isolated cron completes after the daily reset hour (default 4 AM), it bumps updatedAt past the reset boundary, making the session appear "fresh" on the next inbound message.

Result: The daily session reset silently fails. The user gets the previous day's session with stale context instead of a fresh start.

Reproduction

  1. Configure session.reset.mode: "daily" with atHour: 4
  2. Create an isolated cron with sessionKey: "agent:main:main" that runs after 4 AM (e.g., hourly, or scheduled at 5/6/7 AM)
  3. Wait for the cron to complete after 4 AM
  4. Send a message to the main session
  5. Expected: New session (daily reset triggered)
  6. Actual: Same session continues — updatedAt was bumped by the cron run

Suggested Fix

Either:

  • Option A: Use mergeSessionEntryPreserveActivity (already exists in codebase) when persisting isolated cron session entries to parent keys, so updatedAt is not bumped
  • Option B: Isolated cron runs should always write to a namespaced key (e.g., agent:main:cron:<jobId>:run:<runId>) and never to the parent session key directly
  • Option C: evaluateSessionFreshness should ignore updatedAt changes from cron-originated writes (e.g., by tracking lastUserActivityAt separately from updatedAt)

Workaround

Set each isolated cron's sessionKey to a unique value (e.g., agent:main:cron:<job-name>) instead of agent:main:main. This prevents the cron from writing to the main session's store entry.

Environment

  • OpenClaw version: 2026.3.13
  • OS: macOS 26.2 (arm64)
  • Config: session.reset.mode: "daily", atHour: 4
  • Affected cron: any isolated job with sessionKey matching the main session key

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions