Skip to content

[Bug] assemble() always SKIPs: no stateManager (sessionKey=none) — context compaction never runs via afterTurn #878

Description

@dailylights

Summary

The assemble() method is called on every afterTurn but consistently skips with no stateManager (sessionKey=none), because OpenClaw's framework does not pass a sessionKey to the afterTurn hook.

Log Evidence

This appears repeatedly on every turn:

2026-08-09T10:32:38.835+08:00 [plugins] [context-offload] assemble CALLED: msgs=1067, budget=1000000, prompt=none, sessionKey=?
2026-08-09T10:32:38.839+08:00 [plugins] [context-offload] assemble SKIP: no stateManager (sessionKey=none)

Also:

2026-08-09T10:32:38.830+08:00 [plugins] [context-offload] >>> CE.afterTurn CALLED: sessionKey=?

Root Cause

assemble() is reached without a sessionKey, so stateManager cannot be resolved. The assemble() method has a fallback chain (like the compact() fix in #862), but it appears the fallback is not working for the afterTurn path, or the session key is genuinely absent from the hook context.

Impact

  • Context compaction never runs via the afterTurn/assemble path
  • Context window grows unbounded — the L3 token check shows total=474407 msgCount=1068 utilisation=47.4%, but compaction is skipped
  • Memory pressure — the gateway heap grows toward the 608 MiB threshold

Related

Suggested Fix

  • Apply the same sessionKey fallback chain (sessionKey → sessionTarget?.sessionKey → sessionId) to the afterTurn/assemble path
  • Verify the OpenClaw afterTurn hook context actually contains a sessionKey or sessionId

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