Environment
- OpenClaw 2026.3.13 (61d171a), Homebrew, macOS 15.6 arm64, Node 25.6.0
- Plugin: @martian-engineering/lossless-claw v0.5.3 (contextThreshold: 0.75)
- Agent model: anthropic/claude-opus-4-6 (200k ctx)
- Channel: Telegram
Problem
Compaction never triggers despite context reaching 287% capacity (2.9M/1.0M tokens). The agent repeatedly resets the conversation with "Context limit exceeded" instead of compacting. Logs show: [compaction] skipping — no real conversation messages
Root cause
Three independent guards check session.messages.some(hasRealConversationContent) or preparation.messagesToSummarize.some(isRealConversationMessage) and bail out with { ok: true, compacted: false, reason: "no real conversation messages" }. The filter functions themselves appear correct — the issue is that the message arrays arrive empty or unpopulated upstream, so every message fails the filter.
The three locations (line numbers from v2026.3.13 dist):
dist/auth-profiles-DRjqKE3G.js ~line 97903 — plugin-side safeguard
dist/auth-profiles-DDVivXkv.js ~line 102920 — core safeguard
dist/plugin-sdk/thread-bindings-SYAnWHuW.js ~line 93957 — compactEmbeddedPiSessionDirect safeguard
Workaround
Commenting out all three return { ok: true, compacted: false } blocks allows compaction to proceed. After patching, auto-compaction fires and succeeds.
Additional note
When using ollama/qwen2.5:7b as the lossless-claw summaryModel, the LLM sometimes responds with text containing "below threshold" even when context is well over capacity. The classifier at thread-bindings line 93489 (if (text.includes("below threshold")) return "below_threshold") then labels it as a skip, producing the misleading "Compaction skipped: already under target" message. Switching to anthropic/claude-haiku-4-5-20251001 resolved this. This may be worth noting in the lossless-claw docs as a model compatibility issue.
Steps to reproduce
- Install OpenClaw with lossless-claw plugin,
contextThreshold: 0.75
- Use the agent via Telegram until context grows past threshold
- Observe
[compaction] skipping — no real conversation messages in logs
- Context eventually exceeds limit and resets instead of compacting
Expected behavior
Compaction should trigger at the configured threshold without the guards blocking on empty message arrays.
Environment
Problem
Compaction never triggers despite context reaching 287% capacity (2.9M/1.0M tokens). The agent repeatedly resets the conversation with "Context limit exceeded" instead of compacting. Logs show:
[compaction] skipping — no real conversation messagesRoot cause
Three independent guards check
session.messages.some(hasRealConversationContent)orpreparation.messagesToSummarize.some(isRealConversationMessage)and bail out with{ ok: true, compacted: false, reason: "no real conversation messages" }. The filter functions themselves appear correct — the issue is that the message arrays arrive empty or unpopulated upstream, so every message fails the filter.The three locations (line numbers from v2026.3.13 dist):
dist/auth-profiles-DRjqKE3G.js~line 97903 — plugin-side safeguarddist/auth-profiles-DDVivXkv.js~line 102920 — core safeguarddist/plugin-sdk/thread-bindings-SYAnWHuW.js~line 93957 —compactEmbeddedPiSessionDirectsafeguardWorkaround
Commenting out all three
return { ok: true, compacted: false }blocks allows compaction to proceed. After patching, auto-compaction fires and succeeds.Additional note
When using
ollama/qwen2.5:7bas the lossless-clawsummaryModel, the LLM sometimes responds with text containing "below threshold" even when context is well over capacity. The classifier atthread-bindingsline 93489 (if (text.includes("below threshold")) return "below_threshold") then labels it as a skip, producing the misleading "Compaction skipped: already under target" message. Switching toanthropic/claude-haiku-4-5-20251001resolved this. This may be worth noting in the lossless-claw docs as a model compatibility issue.Steps to reproduce
contextThreshold: 0.75[compaction] skipping — no real conversation messagesin logsExpected behavior
Compaction should trigger at the configured threshold without the guards blocking on empty message arrays.