Skip to content

Dreaming narrative sessions never reuse — session key includes timestamp causing unbounded growth #68354

Description

@happer6012

Bug Description

When memory-core dreaming is enabled, the Dream Diary narrative subagent creates a new session on every run instead of reusing an existing one. The session key includes a millisecond timestamp, making it unique each time:

// dreaming-narrative.ts
function buildNarrativeSessionKey(params) {
    const workspaceHash = createHash("sha1").update(params.workspaceDir).digest("hex").slice(0, 12);
    return `dreaming-narrative-${params.phase}-${workspaceHash}-${params.nowMs}`;
    //                                                 ^^^^^^ unique per run
}

This causes unbounded session accumulation in the session store.

Impact

  • Over 4 days (Apr 12–16), 251 orphan dreaming sessions accumulated on the main agent
  • Each session consumed ~19K tokens, totaling ~4.8M tokens wasted
  • The session store index grew from ~4 entries to 255, with no automatic cleanup of the index entries
  • While orphan transcript files get cleaned up after 5 minutes (DREAMING_ORPHAN_MIN_AGE_MS), the session store entries persist indefinitely

Reproduction

  1. Enable dreaming: plugins.entries.memory-core.config.dreaming.enabled = true
  2. Let the dreaming cron run (default: 0 3 * * *) or trigger dreaming manually
  3. Observe session count growing by 2 per run (light + rem phases)

Expected Behavior

The narrative subagent should reuse a single session (or at most one per phase: dreaming-narrative-light and dreaming-narrative-rem) rather than creating a new session each time.

Environment

  • OpenClaw version: 2026.4.14 (323493f)
  • OS: macOS 26.3.1 (arm64)
  • Node: v24.14.0

Suggested Fix

Remove nowMs from the session key, or use a fixed key per agent+phase combination:

function buildNarrativeSessionKey(params) {
    const workspaceHash = createHash("sha1").update(params.workspaceDir).digest("hex").slice(0, 12);
    return `dreaming-narrative-${params.phase}-${workspaceHash}`;
}

The existing orphan cleanup logic already handles transcript files — but the session store entries also need cleanup if unique keys are intentional.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions