Skip to content

memory-core narrative session cleanup fails with missing scope: operator.admin #69886

Description

@ssdash7

Version

OpenClaw 2026.4.15 (041266a), darwin 25.4.0.

Symptom

Every night at 03:00 (local) the Memory Dreaming Promotion cron produces three warn-level gateway log lines:

[plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
[plugins] memory-core: narrative session cleanup failed for rem phase: missing scope: operator.admin
[plugins] memory-core: narrative session cleanup failed for deep phase: missing scope: operator.admin

The dream diary entry itself is written successfully (info log memory-core: dream diary entry written for <phase>), so this is non-functional at the data layer — only the spawned narrative session row is orphaned.

Root cause (bundled dist inspection)

dreaming-narrative-BFx7ugb_.js calls params.subagent.deleteSession({ sessionKey }) in a finally block after the narrative generation run settles. The subagent is built by createGatewaySubagentRuntime() in server.impl-GQ72oJBa.js:17094, which invokes dispatchGatewayMethod("sessions.delete", {...}) with no options argument.

dispatchGatewayMethod (server.impl-GQ72oJBa.js:17008) falls back to createSyntheticOperatorClient() when no plugin-runtime request scope is active. That factory (line 16985) defaults scopes to ["operator.write"]. But sessions.delete is gated under the ADMIN_SCOPE bucket in method-scopes-D3xbsVVt.js (line 150), so it requires operator.admin.

By the time the finally block runs, the original cron-scheduled request scope has unwound — so the synthetic fallback kicks in and the cleanup is rejected. Result: repeated nightly warnings and orphaned narrative sessions.

Suggested fix

One of:

  1. In createGatewaySubagentRuntime().deleteSession, pass { syntheticScopes: ['operator.admin'] } as the third arg to dispatchGatewayMethod — narrowest possible patch.
  2. In dreaming-narrative-BFx7ugb_.js, capture/restore the gateway request scope across the narrative generation boundary so the finally block inherits the cron's scope instead of falling through to synthetic.
  3. Give plugin-runtime-dispatched internal calls a dedicated scope set that includes the minimum privileges each plugin needs (admin for memory-core cleanup).

Option 1 is surgical; option 2 is more correct for any future plugin doing similar cleanup.

Repro

  1. Enable plugins.entries.memory-core.config.dreaming.enabled: true
  2. Let the Memory Dreaming Promotion cron (default 0 3 * * *) run overnight with sufficient short-term memory to trigger narrative generation for all three phases.
  3. Observe warn lines in ~/.openclaw/logs/gateway.err.log.

Workaround in use

Added noise filter in our local ops-issue tracker for plugins + narrative *cleanup failed/wait failed/generation used fallback lines so we stop filing dup issues nightly. Underlying cleanup still fails — orphaned sessions accumulate but haven't caused observable harm yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clawsweeperTracked by ClawSweeper automation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions