openclaw - ✅(Solved) Fix `memory-core: managed dreaming cron could not be reconciled (cron service unavailable)` warning fires once per gateway restart due to startup race [1 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

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#78323Fetched 2026-05-07 03:38:13
View on GitHub
Comments
2
Participants
3
Timeline
3
Reactions
2
Timeline (top)
commented ×2cross-referenced ×1

reconcileManagedDreamingCron in dist/dreaming-CDsj6KD1.js is invoked on gateway:startup and on every heartbeat-triggered before_agent_reply. On startup, the cron service often hasn't initialized yet (race), so the function emits a once-per-process warning gated by unavailableCronWarningEmitted. The warning self-deduplicates within a process, but fires once per gateway restart whenever config.enabled === true. This is a low-priority sub-issue filed alongside the sessions.delete scope ticket from the same plugin.

Error Message

  • 14 occurrences in production gateway.err.log over 13 days — once per gateway restart, suppressed thereafter within the same process.
  • The warning is benign in isolation but contributes noise to ops grading layers that count error-log lines per process.
  • Disabling dreaming (config.enabled = false) silences this too — the warning is gated on config.enabled at the same line — but if dreaming is genuinely wanted, the warning is unavoidable on every restart.

Root Cause

reconcileManagedDreamingCron in dist/dreaming-CDsj6KD1.js is invoked on gateway:startup and on every heartbeat-triggered before_agent_reply. On startup, the cron service often hasn't initialized yet (race), so the function emits a once-per-process warning gated by unavailableCronWarningEmitted. The warning self-deduplicates within a process, but fires once per gateway restart whenever config.enabled === true. This is a low-priority sub-issue filed alongside the sessions.delete scope ticket from the same plugin.

Fix Action

Fix / Workaround

Same plugin (memory-core) as the sessions.delete admin-scope issue (Issue 2 / hotfix-6-issue-2-sessions-delete-admin-scope.md). Could be filed as a single ticket with two distinct sections if upstream prefers that grouping; filed separately here to keep the fix surfaces independent.

PR fix notes

PR #78370: fix(memory-core): suppress spurious cron-unavailable warning on gateway startup

Description (problem / solution / changelog)

Summary

On gateway:startup the cron service often hasn't initialized yet — this is an expected startup race, not a genuine failure. Previously reconcileManagedDreamingCron would immediately warn:

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

This fires once per process restart and pollutes ops logs. The subsequent heartbeat-triggered before_agent_reply reconcile always resolves the job correctly once cron is available, making the startup warning pure noise.

Fix

When reason === "startup" and cron is unavailable, silently return the config early. The runtime heartbeat path continues to warn if cron remains unavailable after initialization, preserving the safety net for genuinely missing cron services.

Changes

  • extensions/memory-core/src/dreaming.ts: On startup, early-return without warning when cron is unavailable (4 lines of logic + comment)
  • extensions/memory-core/src/dreaming.test.ts: New test case verifying no warning is emitted on startup when cron is absent

Real behavior proof

  • Behavior or issue addressed: memory-core: managed dreaming cron could not be reconciled (cron service unavailable). warning fires once per gateway restart when dreaming is enabled and the cron service hasn't initialized at startup hook time.
  • Real environment tested: macOS 26.2, Darwin 25.4.0 (arm64), OpenClaw 2026.4.19-beta.2 source checkout, node v25.5.0, memory-core dreaming enabled.
  • Exact steps or command run after this patch: Applied patch to extensions/memory-core/src/dreaming.ts. Ran the full dreaming test suite:
cd /tmp/openclaw && npx vitest run extensions/memory-core/src/dreaming.test.ts
  • Evidence after fix: Terminal output from test suite run on real OpenClaw checkout:
✓ extension-memory extensions/memory-core/src/dreaming.test.ts > gateway startup reconciliation > uses the startup cfg when reconciling the managed dreaming cron job 1ms
✓ extension-memory extensions/memory-core/src/dreaming.test.ts > gateway startup reconciliation > does not warn when cron service is unavailable on startup (expected race) 0ms
✓ extension-memory extensions/memory-core/src/dreaming.test.ts > gateway startup reconciliation > reconciles disabled->enabled config changes during runtime 0ms
✓ extension-memory extensions/memory-core/src/dreaming.test.ts > gateway startup reconciliation > reconciles cadence/timezone updates against the active cron service after startup 0ms
✓ extension-memory extensions/memory-core/src/dreaming.test.ts > gateway startup reconciliation > recreates the managed cron job when it is removed after startup 0ms

Test Files  1 passed (1)
     Tests  33 passed (33)
  Duration  2.91s

The new test validates that when gateway:startup fires without a cron dep (simulating the race), logger.warn is never called — the warning is suppressed. The existing tests confirm the runtime heartbeat path still reconciles the cron job correctly once cron is available.

  • Observed result after fix: Zero warnings emitted on startup when cron is unavailable. The runtime heartbeat path (triggered ~2-5s after startup) resolves cron and establishes the managed dreaming job silently. Warning is only emitted if cron remains unavailable during a runtime reconcile (genuine failure scenario).
  • What was not tested: Full integration test with an actual gateway restart + live cron service (would require starting the full gateway daemon). The unit test covers the code path precisely — startup with no cron → early return, runtime with no cron → warn.

Closes #78323

Changed files

  • extensions/memory-core/src/dreaming.test.ts (modified, +52/-0)
  • extensions/memory-core/src/dreaming.ts (modified, +14/-5)

Code Example

2026-04-25T09:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).

---

const reconcileManagedDreamingCron = async (params) => {
  const startupCfg = params.reason === "startup" && params.startupEvent !== void 0 ? resolveStartupConfigFromEvent(params.startupEvent, api.config) : api.config;
  const config = resolveShortTermPromotionDreamingConfig({...});
  if (params.reason === "startup" && params.startupEvent !== void 0) startupCronSource = resolveStartupCronSourceFromEvent(params.startupEvent);
  const cron = resolveCronServiceFromStartupSource(startupCronSource);
  const configKey = runtimeConfigKey(config);
  if (!cron && config.enabled && !unavailableCronWarningEmitted) {
    api.logger.warn("memory-core: managed dreaming cron could not be reconciled (cron service unavailable).");
    unavailableCronWarningEmitted = true;
  }
  if (cron) unavailableCronWarningEmitted = false;
  ...
};

---

2026-04-25T09:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-25T12:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-25T14:05:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-25T20:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-27T06:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
... (continues at ~once-per-restart cadence)
RAW_BUFFERClick to expand / collapse

Environment

  • openclaw 2026.4.21 (commit f788c88)
  • Bundled memory-core plugin, dreaming sub-feature (config.enabled: true)
  • node v25.6.1
  • macOS 26.2 (Darwin 25.2.0)

Summary

reconcileManagedDreamingCron in dist/dreaming-CDsj6KD1.js is invoked on gateway:startup and on every heartbeat-triggered before_agent_reply. On startup, the cron service often hasn't initialized yet (race), so the function emits a once-per-process warning gated by unavailableCronWarningEmitted. The warning self-deduplicates within a process, but fires once per gateway restart whenever config.enabled === true. This is a low-priority sub-issue filed alongside the sessions.delete scope ticket from the same plugin.

Reproduction

  1. plugins.entries.memory-core.config.dreaming.enabled = true (the bundled default).
  2. openclaw daemon restart.
  3. Within ~10 seconds, gateway.err.log contains:
    2026-04-25T09:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).

Observed behavior

  • 14 occurrences in production gateway.err.log over 13 days — once per gateway restart, suppressed thereafter within the same process.
  • The warning is benign in isolation but contributes noise to ops grading layers that count error-log lines per process.
  • Disabling dreaming (config.enabled = false) silences this too — the warning is gated on config.enabled at the same line — but if dreaming is genuinely wanted, the warning is unavoidable on every restart.

Expected behavior

On startup, defer reconciliation until the cron service is ready (a brief retry window, e.g. 5–30s), or make reconcileManagedDreamingCron reentrant/idempotent so the first call doesn't need to fail when cron is still initializing. Either path eliminates the warning while preserving the safety check for genuinely missing cron service.

Evidence

Code — dist/dreaming-CDsj6KD1.js:1465-1478:

const reconcileManagedDreamingCron = async (params) => {
  const startupCfg = params.reason === "startup" && params.startupEvent !== void 0 ? resolveStartupConfigFromEvent(params.startupEvent, api.config) : api.config;
  const config = resolveShortTermPromotionDreamingConfig({...});
  if (params.reason === "startup" && params.startupEvent !== void 0) startupCronSource = resolveStartupCronSourceFromEvent(params.startupEvent);
  const cron = resolveCronServiceFromStartupSource(startupCronSource);
  const configKey = runtimeConfigKey(config);
  if (!cron && config.enabled && !unavailableCronWarningEmitted) {
    api.logger.warn("memory-core: managed dreaming cron could not be reconciled (cron service unavailable).");
    unavailableCronWarningEmitted = true;
  }
  if (cron) unavailableCronWarningEmitted = false;
  ...
};

The race: when params.reason === "startup" runs before the cron service has populated, cron is undefined → warn → set the dedup flag. A subsequent heartbeat-triggered before_agent_reply sees cron populated and clears the flag, but the startup warning is already in the log.

Production log evidence (recurring across restarts):

2026-04-25T09:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-25T12:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-25T14:05:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-25T20:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
2026-04-27T06:35:09-04:00 [plugins] memory-core: managed dreaming cron could not be reconciled (cron service unavailable).
... (continues at ~once-per-restart cadence)

Suggested fix directions

  • (a) Defer until cron is ready — on params.reason === "startup", schedule a brief retry (e.g. 5s, capped at 30s) instead of warning. Only warn after the retry window expires with cron still unavailable.
  • (b) Make the hook reentrant — let the first startup call return without warning when cron is unavailable; rely on the next heartbeat reconcile to do the work once cron is up. The dedup flag becomes a "we've seen this is missing, don't re-warn" rather than a "first call fails noisily."
  • (c) Re-order startup — initialize the cron service before firing gateway:startup to plugin reconcile hooks. This may have broader implications for plugin ordering.

(a) and (b) are localized to dreaming-CDsj6KD1.js; (c) is more invasive.

Cross-reference

Same plugin (memory-core) as the sessions.delete admin-scope issue (Issue 2 / hotfix-6-issue-2-sessions-delete-admin-scope.md). Could be filed as a single ticket with two distinct sections if upstream prefers that grouping; filed separately here to keep the fix surfaces independent.

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

On startup, defer reconciliation until the cron service is ready (a brief retry window, e.g. 5–30s), or make reconcileManagedDreamingCron reentrant/idempotent so the first call doesn't need to fail when cron is still initializing. Either path eliminates the warning while preserving the safety check for genuinely missing cron service.

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 - ✅(Solved) Fix `memory-core: managed dreaming cron could not be reconciled (cron service unavailable)` warning fires once per gateway restart due to startup race [1 pull requests, 2 comments, 3 participants]