Skip to content

memory-core: dreaming subagent lacks operator.admin to delete its own session #70353

@ketwi15

Description

@ketwi15

memory-core: dreaming subagent lacks operator.admin to delete its own session

openclaw version: 2026.4.20 (commit 115f05d)
Pre-existing in: at least 2026.4.15

Summary

The dreaming cron in memory-core runs subagent.deleteSession() after generating
a narrative entry, but the embedded subagent runner is invoked without
operator.admin scope. Result: every dream cycle (light, REM, deep × number of
agents) emits narrative session cleanup failed: missing scope: operator.admin.

The narrative itself is generated and written successfully — only the
post-generation session cleanup fails, leaving stale session entries that have to
be cleaned externally.

Reproduction

  1. Configure dreaming:

    "memory-core": {
      "enabled": true,
      "config": { "dreaming": { "enabled": true, "frequency": "0 3 * * *" } }
    }
  2. Wait for cron to fire (or trigger manually)

  3. Observe in /tmp/openclaw/openclaw-YYYY-MM-DD.log:

    memory-core: dreaming cleanup scrubbed 0 stale session entries and archived 42 orphan transcripts.
    memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
    memory-core: narrative session cleanup failed for rem phase: missing scope: operator.admin
    memory-core: narrative session cleanup failed for deep phase: missing scope: operator.admin
    

Source location

dist/dreaming-narrative-D2j0t41s.js:597 (in 2026.4.20):

if (params.subagent) try {
  await params.subagent.deleteSession({ sessionKey });
} catch (cleanupErr) {
  params.logger.warn(`memory-core: narrative session cleanup failed for ${params.data.phase} phase: ${formatErrorMessage(cleanupErr)}`);
}

The subagent context is created by manager-runtime.js for the dreaming sweep
without admin scope. The deleteSession API path requires operator.admin per
server.impl-DYBxSjUs.js:10196 (ADMIN_SCOPE = "operator.admin").

Suggested fix

Either:

  1. Auto-grant operator.admin to the subagent runner spawned by the dreaming cron
    (it's the same trust boundary as the parent gateway, owns its own session).
  2. Provide a subagent.deleteOwnSession() API that doesn't require admin scope
    when called by the session's own creator.
  3. Use a separate cleanup path that doesn't go through the scope-gated HTTP delete.

Impact

  • Repeated WARN log noise (multiple lines per dream cycle × multiple agents)
  • Stale session entries accumulate; require external cleanup script
    (prune-dream-sessions.sh cron at 03:30 UTC handles this for us)
  • managed dreaming cron could not be reconciled (cron service unavailable)
    related warning suggesting the dreaming control plane is partially broken too

Environment

  • LXC container, Debian 12, Node 22.22.2
  • 14 agents, dreaming enabled per agent
  • Cron is running and working (systemctl status cron shows active)
  • Workaround: external prune-dream-sessions.sh at 03:30 UTC catches what
    the failed cleanup leaves behind

Metadata

Metadata

Assignees

No one assigned

    Labels

    clawsweeperTracked by ClawSweeper automation

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions