openclaw - 💡(How to fix) Fix `sessions.delete` requires `operator.admin` (wildcard); bundled `memory-core` cannot delete the session it itself created [1 comments, 2 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#78322Fetched 2026-05-07 03:38:14
View on GitHub
Comments
1
Participants
2
Timeline
8
Reactions
2
Timeline (top)
mentioned ×3subscribed ×3closed ×1commented ×1

The dreaming subagent in the bundled memory-core plugin creates its own narrative-generation session per phase (light, rem, deep), runs the narrative job, and then attempts to clean up by calling subagent.deleteSession({ sessionKey }). That call hits sessions.delete, which in dist/method-scopes-DtjYAsKK.js is mapped exclusively to ADMIN_SCOPE (operator.admin) — a wildcard scope covering ~25 admin methods (full agents/skills/secrets/cron/sessions mutation, chat injection, agent-files write, web login, channels start/logout). The dreaming subagent runs without operator.admin, so the cleanup fails on every phase, every cycle. There is no narrower scope for "delete a session this caller itself created."

Functional impact: stale dreaming-narrative-{light,rem,deep}-* sessions accumulate in ~/.openclaw/agents/main/sessions/sessions.json indefinitely. Production saw 39 of 55 entries (71%) become stale dreaming-narrative-* over a 13-day window — a compounding rate of ~9/day with no built-in reaper.

Error Message

  • 30 occurrences of narrative session cleanup failed for ... phase: missing scope: operator.admin in production gateway.err.log over a 10-day window (3 phases × 1 cycle/day × ~10 days).
  • 39 stale dreaming-narrative-* sessions accumulated in sessions.json (71% of total entries) over 13 days.
  • Granting operator.admin to the dreaming subagent solely so it can self-clean would expand its blast radius to ~25 unrelated admin methods (agent CRUD, secret reload, cron mutation, all destructive sessions ops, chat injection, agent-files write). Massively over-privileged for a single self-scoped session-delete.

Root Cause

  • (a) Introduce a narrower scope — e.g. operator.sessions.delete.self. Define it as: "delete a session whose creator-subagent context matches the caller." Downgrade the subagent.deleteSession callsite to require only this scope when the target sessionKey corresponds to a session the caller created. Authorize the dreaming-narrative-* cleanup with this scope rather than operator.admin.
  • (b) Auto-elevate scoped to the lifecycle-cleanup operation — when a subagent calls deleteSession on a session it itself opened (creator-subagent matches caller), the runtime grants sessions.delete for the duration of that single call without exposing the rest of operator.admin.
  • (c) Skip the gateway round-trip for self-owned cleanup — let the subagent runtime delete its own session record in-process when the session was opened by that same runtime. The scope check is moot because the operation never reaches the scoped method dispatch.

Fix Action

Workaround

Disable the feature (plugins.entries.memory-core.config.dreaming.enabled = false). This silences both the cleanup-fail warnings and the accumulating stale sessions, but it's a heavy hammer for a self-clean bug — and only viable for users whose downstream consumer of dream-diary data is also disabled. Users who actively use the dream-diary product currently have no remediation other than granting operator.admin to the subagent (massively over-privileged) or living with unbounded session growth.

Code Example

2026-04-26T03:00:31-04:00 [plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
   2026-04-26T03:00:46-04:00 [plugins] memory-core: narrative session cleanup failed for rem phase: missing scope: operator.admin
   2026-04-26T03:01:06-04:00 [plugins] memory-core: narrative session cleanup failed for deep phase: missing scope: operator.admin

---

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)}`);
}

---

function buildNarrativeSessionKey(params) {
  ...
  return `dreaming-narrative-${params.phase}-${workspaceHash}-${params.nowMs}`;
}

---

[ADMIN_SCOPE]: [
  "channels.start",
  "channels.logout",
  "agents.create",
  "agents.update",
  "agents.delete",
  "skills.install",
  "skills.update",
  "secrets.reload",
  "secrets.resolve",
  "cron.add",
  "cron.update",
  "cron.remove",
  "cron.run",
  "sessions.patch",
  "sessions.reset",
  "sessions.delete",
  "sessions.compact",
  "sessions.compaction.restore",
  "connect",
  "chat.inject",
  "web.login.start",
  "web.login.wait",
  "set-heartbeats",
  "system-event",
  "agents.files.set"
]

---

function authorizeOperatorScopesForMethod(method, scopes) {
  if (scopes.includes("operator.admin")) return { allowed: true };
  ...
}

---

2026-04-26T03:00:31-04:00 [plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
2026-04-26T03:00:46-04:00 [plugins] memory-core: narrative session cleanup failed for rem phase: missing scope: operator.admin
2026-04-26T03:01:06-04:00 [plugins] memory-core: narrative session cleanup failed for deep phase: missing scope: operator.admin
2026-04-27T03:00:20-04:00 [plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
... (continues daily through 2026-04-30+)
RAW_BUFFERClick to expand / collapse

Environment

  • openclaw 2026.4.21 (commit f788c88)
  • Bundled memory-core plugin, dreaming sub-feature (config.enabled: true)
  • node v25.6.1
  • macOS 26.2 (Darwin 25.2.0)

Summary

The dreaming subagent in the bundled memory-core plugin creates its own narrative-generation session per phase (light, rem, deep), runs the narrative job, and then attempts to clean up by calling subagent.deleteSession({ sessionKey }). That call hits sessions.delete, which in dist/method-scopes-DtjYAsKK.js is mapped exclusively to ADMIN_SCOPE (operator.admin) — a wildcard scope covering ~25 admin methods (full agents/skills/secrets/cron/sessions mutation, chat injection, agent-files write, web login, channels start/logout). The dreaming subagent runs without operator.admin, so the cleanup fails on every phase, every cycle. There is no narrower scope for "delete a session this caller itself created."

Functional impact: stale dreaming-narrative-{light,rem,deep}-* sessions accumulate in ~/.openclaw/agents/main/sessions/sessions.json indefinitely. Production saw 39 of 55 entries (71%) become stale dreaming-narrative-* over a 13-day window — a compounding rate of ~9/day with no built-in reaper.

Reproduction

  1. Default config: plugins.entries.memory-core.config.dreaming.enabled = true (the bundled default).
  2. Wait for the 03:00 ET dreaming cron cycle (or whatever the configured trigger is).
  3. gateway.err.log:
    2026-04-26T03:00:31-04:00 [plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
    2026-04-26T03:00:46-04:00 [plugins] memory-core: narrative session cleanup failed for rem phase: missing scope: operator.admin
    2026-04-26T03:01:06-04:00 [plugins] memory-core: narrative session cleanup failed for deep phase: missing scope: operator.admin
  4. Inspect ~/.openclaw/agents/main/sessions/sessions.json after several cycles. dreaming-narrative-{phase}-* entries accumulate without ever being removed.

Observed behavior

  • 30 occurrences of narrative session cleanup failed for ... phase: missing scope: operator.admin in production gateway.err.log over a 10-day window (3 phases × 1 cycle/day × ~10 days).
  • 39 stale dreaming-narrative-* sessions accumulated in sessions.json (71% of total entries) over 13 days.
  • Granting operator.admin to the dreaming subagent solely so it can self-clean would expand its blast radius to ~25 unrelated admin methods (agent CRUD, secret reload, cron mutation, all destructive sessions ops, chat injection, agent-files write). Massively over-privileged for a single self-scoped session-delete.

Expected behavior

A subagent operation that creates a session should be able to remove that same session at the end of its own lifecycle without acquiring scopes for ~25 unrelated admin methods. Either (i) introduce a narrower scope, or (ii) auto-elevate the lifecycle-cleanup operation transparently for the duration of the self-scoped delete, or (iii) avoid the gateway round-trip entirely and let the subagent runtime delete its own session in-process.

Evidence

Cleanup call site — dist/dreaming-narrative-DcGYNs84.js:594-598:

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)}`);
}

Session key construction — same module, lines 95–97:

function buildNarrativeSessionKey(params) {
  ...
  return `dreaming-narrative-${params.phase}-${workspaceHash}-${params.nowMs}`;
}

The session being deleted was created earlier in the same flow (line 537: const sessionKey = buildNarrativeSessionKey({...})). Creator-subagent and target-subagent are the same identity — there is no cross-agent delete here.

Scope mapping — dist/method-scopes-DtjYAsKK.js:136-162:

[ADMIN_SCOPE]: [
  "channels.start",
  "channels.logout",
  "agents.create",
  "agents.update",
  "agents.delete",
  "skills.install",
  "skills.update",
  "secrets.reload",
  "secrets.resolve",
  "cron.add",
  "cron.update",
  "cron.remove",
  "cron.run",
  "sessions.patch",
  "sessions.reset",
  "sessions.delete",
  "sessions.compact",
  "sessions.compaction.restore",
  "connect",
  "chat.inject",
  "web.login.start",
  "web.login.wait",
  "set-heartbeats",
  "system-event",
  "agents.files.set"
]

sessions.delete sits in the same bucket as agents.delete, secrets.reload, cron.run, and chat.inject.

Auth path — same file, line 187+:

function authorizeOperatorScopesForMethod(method, scopes) {
  if (scopes.includes("operator.admin")) return { allowed: true };
  ...
}

operator.admin is a wildcard-yes; there is no narrower path.

Production log evidence (recurring daily, every phase):

2026-04-26T03:00:31-04:00 [plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
2026-04-26T03:00:46-04:00 [plugins] memory-core: narrative session cleanup failed for rem phase: missing scope: operator.admin
2026-04-26T03:01:06-04:00 [plugins] memory-core: narrative session cleanup failed for deep phase: missing scope: operator.admin
2026-04-27T03:00:20-04:00 [plugins] memory-core: narrative session cleanup failed for light phase: missing scope: operator.admin
... (continues daily through 2026-04-30+)

Suggested fix directions

  • (a) Introduce a narrower scope — e.g. operator.sessions.delete.self. Define it as: "delete a session whose creator-subagent context matches the caller." Downgrade the subagent.deleteSession callsite to require only this scope when the target sessionKey corresponds to a session the caller created. Authorize the dreaming-narrative-* cleanup with this scope rather than operator.admin.
  • (b) Auto-elevate scoped to the lifecycle-cleanup operation — when a subagent calls deleteSession on a session it itself opened (creator-subagent matches caller), the runtime grants sessions.delete for the duration of that single call without exposing the rest of operator.admin.
  • (c) Skip the gateway round-trip for self-owned cleanup — let the subagent runtime delete its own session record in-process when the session was opened by that same runtime. The scope check is moot because the operation never reaches the scoped method dispatch.

(a) is the most general and most reusable for any future "subagent manages its own resources" pattern. (c) is the narrowest fix for this specific cleanup path.

Workaround

Disable the feature (plugins.entries.memory-core.config.dreaming.enabled = false). This silences both the cleanup-fail warnings and the accumulating stale sessions, but it's a heavy hammer for a self-clean bug — and only viable for users whose downstream consumer of dream-diary data is also disabled. Users who actively use the dream-diary product currently have no remediation other than granting operator.admin to the subagent (massively over-privileged) or living with unbounded session growth.

Cross-reference

This issue stems from the same plugin (memory-core) as the cron startup-race warning filed separately (Issue 3 / hotfix-6-issue-3-cron-startup-race.md). They share config.dreaming.enabled as a kill switch but are otherwise unrelated code paths.

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…

FAQ

Expected behavior

A subagent operation that creates a session should be able to remove that same session at the end of its own lifecycle without acquiring scopes for ~25 unrelated admin methods. Either (i) introduce a narrower scope, or (ii) auto-elevate the lifecycle-cleanup operation transparently for the duration of the self-scoped delete, or (iii) avoid the gateway round-trip entirely and let the subagent runtime delete its own session in-process.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix `sessions.delete` requires `operator.admin` (wildcard); bundled `memory-core` cannot delete the session it itself created [1 comments, 2 participants]