Skip to content

[Bug]: Safeguard compaction permanently blocked by Pi SDK auto-compaction (consecutive failures) #73003

@bradhallett

Description

@bradhallett

Bug Report: OpenClaw Safeguard Compaction Permanently Blocked by Pi SDK Auto-Compaction

Summary

When compaction.mode = "safeguard" is configured, OpenClaw's preflight compaction is permanently blocked by the Pi SDK's internal auto-compaction. The two systems operate on different thresholds and do not coordinate, causing a conflict where the session grows unchecked until overflow.

Environment

  • OpenClaw: 2026.4.24 (cbcfdf6)
  • Pi SDK: @mariozechner/pi-coding-agent 0.70.2
  • Model: zai/glm-5.1 (202,800 token context window)
  • OS: macOS 15.4 (arm64), Mac Studio M2 Ultra
  • Session type: Telegram direct message (long-running, high-turnover)

Configuration

{
  "agents": {
    "defaults": {
      "compaction": {
        "mode": "safeguard",
        "reserveTokens": 110000,
        "keepRecentTokens": 40000,
        "recentTurnsPreserve": 3,
        "truncateAfterCompaction": true,
        "memoryFlush": {
          "enabled": true,
          "softThresholdTokens": 8000
        }
      }
    }
  }
}

Root Cause

Two independent compaction systems operate on the same session with no coordination:

1. Pi SDK Auto-Compaction (runs inside AgentSession)

  • Triggered after every agent_end event when contextTokens > contextWindow - reserveTokens
  • Uses Pi SDK defaults: reserveTokens: 16,384, keepRecentTokens: 20,000
  • Does NOT respect OpenClaw's compaction config (110K reserve, 40K keepRecent)
  • Threshold: 202,800 - 16,384 = 186,416 tokens

2. OpenClaw Safeguard Preflight Compaction

  • Triggered before each agent response when tokens exceed budget
  • Uses OpenClaw config: reserveTokens: 110,000, keepRecentTokens: 40,000
  • Threshold: 202,800 - 110,000 - 8,000 = 84,800 tokens

The Conflict

  1. Session grows past 186K tokens → Pi auto-compaction fires → succeeds → appends compaction entry
  2. After Pi compaction, session is ~40-60K tokens (Pi kept only 20K recent)
  3. This is below Pi's threshold (186K) so Pi won't fire again
  4. But it's above OpenClaw's threshold (84.8K) so OpenClaw tries to compact
  5. OpenClaw opens the session file → prepareCompaction() checks if last branch entry is compaction → yes → returns undefined
  6. Pi SDK throws "Already compacted" → OpenClaw logs already_compacted_recently
  7. Session keeps growing → eventually overflows

Missing Guard

applyPiAutoCompactionGuard() exists but is only invoked for context engines that declare ownsCompaction === true. Safeguard mode has no context engine, so Pi auto-compaction remains active, creating the conflict.

Relevant source:

  • selection-C3otDzGD.js:6252 — applies guard only for context engines
  • pi-settings-DnGbeiAj.js:62 — guard implementation
  • compact-c7yzX715.js — safeguard compaction path (never calls the guard)

Evidence

Session file analysis

  • Session: ca5e958f-d6ca-4914-b8e4-76d06a799548.jsonl
  • 15 compaction entries in the session (all from Pi auto-compaction)
  • Compaction interval: every 4-23 minutes
  • File grew to 3.8 MB / 1,357 entries despite 15 compactions

Log evidence (all from Telegram session agent:main:telegram:direct:8089459921)

2026-04-27T11:31:55 outcome=failed reason=already_compacted_recently
2026-04-27T11:46:42 outcome=failed reason=already_compacted_recently
2026-04-27T12:03:15 outcome=failed reason=already_compacted_recently
2026-04-27T12:21:40 outcome=failed reason=already_compacted_recently
2026-04-27T13:07:08 outcome=failed reason=already_compacted_recently
2026-04-27T13:13:36 outcome=failed reason=already_compacted_recently
2026-04-27T13:35:43 outcome=failed reason=already_compacted_recently
2026-04-27T14:00:16 outcome=failed reason=already_compacted_recently
2026-04-27T14:10:48 outcome=failed reason=already_compacted_recently
2026-04-27T14:33:54 outcome=failed reason=already_compacted_recently
2026-04-27T14:55:17 outcome=failed reason=already_compacted_recently
2026-04-27T15:10:08 outcome=failed reason=already_compacted_recently

13 consecutive failures, zero successes over 4 hours. Not a single OpenClaw safeguard compaction succeeded.

Cascading impact

  • Stuck sessions (30-120s processing time)
  • Context overflow crashes (2 observed)
  • Rate limit exhaustion from cascading fallbacks
  • sqlite-vec warnings from concurrent stress

Suggested Fix

In the safeguard compaction path (compact-c7yzX715.js), disable Pi SDK auto-compaction when OpenClaw owns the compaction lifecycle:

// After line 825 where applyPiCompactionSettingsFromConfig is called, add:
if (compactionMode === "safeguard") {
    settingsManager.setCompactionEnabled(false);
}

Alternatively, extend applyPiAutoCompactionGuard() to recognize safeguard mode:

function shouldDisablePiAutoCompaction(params) {
    return params.contextEngineInfo?.ownsCompaction === true 
        || params.compactionMode === "safeguard";  // ← Add this
}

Workaround

Users can work around this by using compaction.mode = "off" and relying solely on Pi SDK auto-compaction (with adjusted thresholds), or by using a context engine that declares ownsCompaction.

Severity

High — Safeguard mode is specifically designed to prevent context overflow, but this bug makes it completely ineffective for long-running sessions. The "safeguard" provides a false sense of security while the session grows uncontrolled.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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