Skip to content

[BUG] /compact fails with 'no_session_manager' — Context Engine compact() receives no sessionKey #862

Description

@dailylights

Environment

  • OpenClaw: 2026.7.2-beta.7 (dabe191)
  • Node.js: v24.18.0
  • Plugin: @tencentdb-agent-memory/memory-tencentdb@1.0.1 (local mode)
  • OS: Debian 13 (Linux 6.12.95+deb13-amd64)

Summary

Running /compact slash command fails with Compaction failed: no_session_manager.

The OffloadContextEngine.compact() method returns { ok: false, compacted: false, reason: "no_session_manager" } because OpenClaw's framework calls compact() without passing a sessionKey.

Reproduced with Debug Logging

Enabled debug logging and triggered compaction. The complete log chain:

2026-08-08T14:55:56.477+08:00 [plugins] [context-offload] >>> CE.compact CALLED: sessionKey=?
2026-08-08T14:55:56.481+08:00 [plugins] [context-offload] >>> compact START: params={sessionId:faaaf089-8cd8-4d4c-9cb8-cfb613f6f735,agentId:main,tokenBudget:1000000,compactionTarget:threshold,force:true,abortSignal:{}}
2026-08-08T14:55:56.485+08:00 [plugins] [context-offload] <<< compact SKIP: no session manager (8ms)

Critical evidence: The compact START log shows the exact params received by compact():

{
  "sessionId": "faaaf089-8cd8-4d4c-9cb8-cfb613f6f735",
  "agentId": "main",
  "tokenBudget": 1000000,
  "compactionTarget": "threshold",
  "force": true,
  "abortSignal": {}
}

There is NO sessionKey field in the params. The sessionKey=? in the first log confirms params.sessionKey is undefined.

Root Cause

Plugin Side — OffloadContextEngine.compact() (offload/index.ts:2144)

async compact(params: any) {
    let stateManager = params._offloadManager;
    if (!stateManager && params.sessionKey) {   // ← params.sessionKey is undefined → block SKIPPED
      try {
        const entry = await this._sessions.resolveIfAllowed(params.sessionKey, params.sessionId);
        if (entry) stateManager = entry.manager;
      } catch { /* ignore */ }
    }
    ...
    if (!stateManager) {
      logger.warn(`<<< compact SKIP: no session manager (${Date.now() - _compactStart}ms)`);
      return { ok: false, compacted: false, reason: "no_session_manager" };
    }
}

The guard if (!stateManager && params.sessionKey) requires params.sessionKey to be truthy. When OpenClaw calls compact() without sessionKey, stateManager remains undefined and the method immediately returns no_session_manager.

Why This Is a Plugin Bug (not just framework)

The plugin's compact() method is too strict. Even when sessionKey is missing, it should attempt to resolve the session manager using sessionId (which IS present) or sessionTarget.sessionKey. The assemble() method already handles this correctly with a fallback chain.

Impact

  • /compact manual command fails with no_session_manager
  • sessions.compact RPC fails with the same error
  • Automatic compaction is NOT affected: goes through assemble() which has correct sessionKey fallback
  • Other offload hooks (after_tool_call, before_prompt_build) work correctly

Suggested Fix

In src/offload/index.ts, OffloadContextEngine.compact():

async compact(params: any) {
    let stateManager = params._offloadManager;
    // FIX: fall back to sessionTarget.sessionKey or sessionId when sessionKey is missing
    const effectiveSessionKey = params.sessionKey ?? params.sessionTarget?.sessionKey ?? params.sessionId;
    if (!stateManager && effectiveSessionKey) {
      try {
        const entry = await this._sessions.resolveIfAllowed(effectiveSessionKey, params.sessionId);
        if (entry) stateManager = entry.manager;
      } catch { /* ignore */ }
    }
    ...
    if (!stateManager) {
      logger.warn(`<<< compact SKIP: no session manager (${Date.now() - _compactStart}ms)`);
      return { ok: false, compacted: false, reason: "no_session_manager" };
    }
    ...
}

Priority

P1/compact manual command is broken, but automatic compaction and offload collection still work.

Related

  • No existing issue found for this exact problem in either OpenClaw or TencentDB-Agent-Memory.
  • The assemble() method in the same file already handles sessionKey fallback correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions