Skip to content

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

@ssdash7

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
    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