openclaw - 💡(How to fix) Fix [Bug]: PR #71694 runtime cron service fallback ineffective on Linux v2026.4.25 — `gatewayContext.getCron()` returns null [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#72835Fetched 2026-04-28 06:31:44
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
closed ×1commented ×1

PR #71694 ("fix(memory-core): add runtime cron service fallback for dreaming reconciliation", merged 2026-04-25) intends to recover the dreaming cron reconciliation when the startup capture is null by falling back to resolveCronServiceFromGatewayContext(gatewayContext). On a fresh Linux Debian 11 install of v2026.4.25, both layers return null and the warning still fires:

memory-core: managed dreaming cron could not be reconciled (cron service unavailable).

The new unavailableCronWarningEmitted flag correctly limits emissions to one per gateway lifetime (vs. v4.23's hourly XX:46 cadence), which is an improvement in noise, but the underlying cron registration still does not succeed — managed scheduler dispatch at the configured 0 3 * * * daily fire never runs in production. Manual openclaw cron run <jobId> continues to work because that path bypasses the scheduler binding.

Error Message

api.logger.warn("memory-core: managed dreaming cron could not be reconciled (cron service unavailable).");

Root Cause

The new unavailableCronWarningEmitted flag correctly limits emissions to one per gateway lifetime (vs. v4.23's hourly XX:46 cadence), which is an improvement in noise, but the underlying cron registration still does not succeed — managed scheduler dispatch at the configured 0 3 * * * daily fire never runs in production. Manual openclaw cron run <jobId> continues to work because that path bypasses the scheduler binding.

Fix Action

Fix / Workaround

The new unavailableCronWarningEmitted flag correctly limits emissions to one per gateway lifetime (vs. v4.23's hourly XX:46 cadence), which is an improvement in noise, but the underlying cron registration still does not succeed — managed scheduler dispatch at the configured 0 3 * * * daily fire never runs in production. Manual openclaw cron run <jobId> continues to work because that path bypasses the scheduler binding.

After PR #71694, state.deps.cron is captured at runtime via gatewayContext.getCron() if startup capture missed it. Warning should not fire, and the scheduler should dispatch the configured daily cron.

Warning fires once at ~5min post-restart. End-to-end dreaming via openclaw cron run <id> works (light/rem/deep all complete, events.jsonl shows memory.dream.completed for all phases); but the upstream scheduler never dispatches the configured 0 3 * * * Asia/Taipei job — observable by openclaw cron list showing Status: skipped, Last: 18h ago even after manual triggers succeed.

Code Example

memory-core: managed dreaming cron could not be reconciled (cron service unavailable).

---

const reconcileManagedDreamingCron = async (params) => {
    // ...
    if (params.reason === "startup") resolveStartupCron = params.startupCron ?? null;
    let cron = resolveStartupCron?.() ?? null;
    if (!cron && params.reason === "runtime" && gatewayContext) try {
        cron = resolveCronServiceFromGatewayContext(gatewayContext);
        if (cron) resolveStartupCron = () => cron;
    } catch {}
    // ...
    if (!cron && config.enabled && !unavailableCronWarningEmitted) {
        // ...
        api.logger.warn("memory-core: managed dreaming cron could not be reconciled (cron service unavailable).");
        unavailableCronWarningEmitted = true;
    }
}

---

function resolveCronServiceFromGatewayContext(context) {
    return resolveCronServiceFromCandidate(context?.getCron?.());
}
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

PR #71694 ("fix(memory-core): add runtime cron service fallback for dreaming reconciliation", merged 2026-04-25) intends to recover the dreaming cron reconciliation when the startup capture is null by falling back to resolveCronServiceFromGatewayContext(gatewayContext). On a fresh Linux Debian 11 install of v2026.4.25, both layers return null and the warning still fires:

memory-core: managed dreaming cron could not be reconciled (cron service unavailable).

The new unavailableCronWarningEmitted flag correctly limits emissions to one per gateway lifetime (vs. v4.23's hourly XX:46 cadence), which is an improvement in noise, but the underlying cron registration still does not succeed — managed scheduler dispatch at the configured 0 3 * * * daily fire never runs in production. Manual openclaw cron run <jobId> continues to work because that path bypasses the scheduler binding.

Steps to reproduce

  1. npm install -g [email protected] --ignore-scripts on Debian 11 (Node 24.13.0, NVM)
  2. Run base npm install --omit=dev --ignore-scripts --legacy-peer-deps and the eager bundled-plugin postinstall (OPENCLAW_EAGER_BUNDLED_PLUGIN_DEPS=1 node scripts/postinstall-bundled-plugins.mjs)
  3. Restart openclaw-gateway.service (user systemd)
  4. Wait ≥5 minutes
  5. grep -c 'cron service unavailable' /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log

Expected behavior

After PR #71694, state.deps.cron is captured at runtime via gatewayContext.getCron() if startup capture missed it. Warning should not fire, and the scheduler should dispatch the configured daily cron.

Actual behavior

Warning fires once at ~5min post-restart. End-to-end dreaming via openclaw cron run <id> works (light/rem/deep all complete, events.jsonl shows memory.dream.completed for all phases); but the upstream scheduler never dispatches the configured 0 3 * * * Asia/Taipei job — observable by openclaw cron list showing Status: skipped, Last: 18h ago even after manual triggers succeed.

Source-level evidence

The warning emission is at dist/dreaming-CdZwJUa6.js:1536. Looking at the runtime fallback path (lines 1517–1545):

const reconcileManagedDreamingCron = async (params) => {
    // ...
    if (params.reason === "startup") resolveStartupCron = params.startupCron ?? null;
    let cron = resolveStartupCron?.() ?? null;
    if (!cron && params.reason === "runtime" && gatewayContext) try {
        cron = resolveCronServiceFromGatewayContext(gatewayContext);
        if (cron) resolveStartupCron = () => cron;
    } catch {}
    // ...
    if (!cron && config.enabled && !unavailableCronWarningEmitted) {
        // ...
        api.logger.warn("memory-core: managed dreaming cron could not be reconciled (cron service unavailable).");
        unavailableCronWarningEmitted = true;
    }
}

resolveCronServiceFromGatewayContext at line 1266 simply does:

function resolveCronServiceFromGatewayContext(context) {
    return resolveCronServiceFromCandidate(context?.getCron?.());
}

In our deployment, context.getCron() returns null (gatewayContext is set non-null at line 1555 — gatewayContext = ctx — but its .getCron() produces null). So both fallbacks fail. The deeper question is why context.getCron does not return a real cron service handle at runtime on Linux.

Environment

ItemValue
OpenClaw version2026.4.25 (stable)
OSDebian 11 (AWS Bitnami)
Node24.13.0 (NVM)
Installnpm install -g [email protected] --ignore-scripts
Gateway servicesystemd user-level
Heartbeat configevery: 1h, activeHours: 08:00–23:00 Asia/Taipei

Workaround in place

A system crontab entry at 55 14 * * * UTC (22:55 Asia/Taipei) calls openclaw cron run <jobId> directly, bypassing the broken scheduler binding. This has been operational since 2026-04-17 across v4.15 → v4.20 → v4.22 → v4.23 → v4.25.

Related

  • #67362 (closed by #71694)
  • #71694 (the merged fix)
  • #71737 (RFC: scheduler lifecycle)

extent analysis

TL;DR

The context.getCron() function returns null, causing the cron service reconciliation to fail, and a workaround is needed to ensure the scheduled job runs as expected.

Guidance

  • Investigate why context.getCron() returns null on Linux Debian 11, considering the gatewayContext is set non-null.
  • Verify the resolveCronServiceFromGatewayContext function is correctly implemented and returns a valid cron service handle.
  • Check the system configuration and environment variables to ensure they are correctly set for the cron job to run.
  • Consider implementing a temporary workaround, such as the existing system crontab entry, to ensure the scheduled job runs until the underlying issue is resolved.

Example

No code snippet is provided as the issue is more related to configuration and environment setup.

Notes

The issue seems to be specific to the Linux Debian 11 environment, and the context.getCron() function returning null is the root cause of the problem. Further investigation is needed to determine why this function returns null.

Recommendation

Apply a workaround, such as the existing system crontab entry, to ensure the scheduled job runs until the underlying issue with context.getCron() is resolved. This will allow the system to function as expected while a more permanent solution is developed.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

After PR #71694, state.deps.cron is captured at runtime via gatewayContext.getCron() if startup capture missed it. Warning should not fire, and the scheduler should dispatch the configured daily cron.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: PR #71694 runtime cron service fallback ineffective on Linux v2026.4.25 — `gatewayContext.getCron()` returns null [1 comments, 2 participants]