openclaw - 💡(How to fix) Fix Bug: memory-core dreaming cron job never registered due to gateway:startup hook timing race [1 comments, 1 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#63428Fetched 2026-04-09 07:53:51
View on GitHub
Comments
1
Participants
1
Timeline
2
Reactions
0
Author
Participants
Timeline (top)
closed ×1commented ×1

The memory-core plugin's dreaming cron job is never registered because of a startup timing race condition.

Root Cause

In server.impl-WjqjRArz.js (line ~27181), the gateway:startup hook is triggered via setTimeout(250ms):

// startup hook fires early
setTimeout(() => {
    triggerInternalHook(createInternalHookEvent("gateway", "startup", ...));
}, 250);

// plugin services start AFTER the timeout fires
let pluginServices = await startPluginServices({ ... });

The memory-core plugin calls registerShortTermPromotionDreaming(api) inside its register() method, which registers a hook for "gateway:startup". But by the time startPluginServices completes and the plugin's register() runs, the gateway:startup event has already been dispatched (250ms earlier). The hook handler is registered but never called.

As a result, reconcileShortTermDreamingCronJob() never executes, and no dreaming cron job is ever created.

Fix Action

Workaround

Manually adding the dreaming cron job to jobs.json while the gateway is running works — the job is not removed at runtime. However, on the next gateway restart, the internal cron state may not preserve manually-added jobs.

Code Example

// startup hook fires early
setTimeout(() => {
    triggerInternalHook(createInternalHookEvent("gateway", "startup", ...));
}, 250);

// plugin services start AFTER the timeout fires
let pluginServices = await startPluginServices({ ... });
RAW_BUFFERClick to expand / collapse

Description

The memory-core plugin's dreaming cron job is never registered because of a startup timing race condition.

Root Cause

In server.impl-WjqjRArz.js (line ~27181), the gateway:startup hook is triggered via setTimeout(250ms):

// startup hook fires early
setTimeout(() => {
    triggerInternalHook(createInternalHookEvent("gateway", "startup", ...));
}, 250);

// plugin services start AFTER the timeout fires
let pluginServices = await startPluginServices({ ... });

The memory-core plugin calls registerShortTermPromotionDreaming(api) inside its register() method, which registers a hook for "gateway:startup". But by the time startPluginServices completes and the plugin's register() runs, the gateway:startup event has already been dispatched (250ms earlier). The hook handler is registered but never called.

As a result, reconcileShortTermDreamingCronJob() never executes, and no dreaming cron job is ever created.

Observed Behavior

  • Gateway logs show "ready (3 plugins, 0.8s)" but zero dreaming-related log output.
  • ~/.openclaw/cron/jobs.json contains no dreaming cron job.
  • ~/.openclaw/workspace/DREAMS.md is never created.
  • ~/.openclaw/workspace/memory/.dreams/ never gets dreaming reports.
  • On April 7, the dreaming cron was created once ("memory-core: created managed dreaming cron job."), but after a Gateway crash-restart on April 8, it was removed and never re-created despite 8+ subsequent restarts.

Workaround

Manually adding the dreaming cron job to jobs.json while the gateway is running works — the job is not removed at runtime. However, on the next gateway restart, the internal cron state may not preserve manually-added jobs.

Environment

  • OpenClaw: 2026.4.5 → 2026.4.8 (both affected)
  • Node: v22.22.0
  • OS: Linux 6.8.0-106-generic (x64)
  • Config: plugins.entries.memory-core.config.dreaming.enabled: true, plugins.slots.memory: "memory-core"

Suggested Fix

Either:

  1. Trigger gateway:startup after startPluginServices completes, or
  2. Add a late-registration mechanism that fires newly registered "gateway:startup" hooks immediately if the event has already occurred, or
  3. Call reconcileShortTermDreamingCronJob() from a different lifecycle hook that fires after plugins are loaded.

Relevant Source

  • Hook trigger: server.impl-WjqjRArz.js:27181
  • Plugin register: extensions/memory-core/index.js:683 (registerShortTermPromotionDreaming(api))
  • Hook registration: dreaming-looUjKfS.js:1458 (api.registerHook("gateway:startup", ...))
  • Reconcile function: dreaming-looUjKfS.js:1268 (reconcileShortTermDreamingCronJob)

extent analysis

TL;DR

Trigger the gateway:startup hook after startPluginServices completes to ensure the memory-core plugin's dreaming cron job is registered.

Guidance

  • Review the server.impl-WjqjRArz.js file (around line 27181) to understand the current implementation of the gateway:startup hook trigger via setTimeout.
  • Consider modifying the gateway:startup hook trigger to fire after startPluginServices completes, ensuring plugins are loaded before the hook is triggered.
  • Alternatively, explore adding a late-registration mechanism for newly registered hooks to fire immediately if the corresponding event has already occurred.
  • Verify the fix by checking for the presence of the dreaming cron job in ~/.openclaw/cron/jobs.json and the creation of ~/.openclaw/workspace/DREAMS.md after applying the suggested fix.

Example

No code snippet is provided as the issue does not require a specific code change, but rather a change in the timing of the gateway:startup hook trigger.

Notes

The suggested fix assumes that the gateway:startup hook trigger is the primary cause of the issue. However, other factors might contribute to the problem, and additional debugging may be necessary.

Recommendation

Apply a workaround by triggering the gateway:startup hook after startPluginServices completes, as this approach directly addresses the identified root cause and has a high likelihood of resolving the issue.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING