#4223: fix: compaction safeguard falls through when ctx.model is unavailable
agents
Cluster:
Compaction Safeguards and Summaries
## Problem
When Clawdbot runs in embedded mode, `extensionRunner.initialize()` is never called. This means `ExtensionRunner.getModel` stays at its default `() => undefined`.
When the compaction safeguard extension runs, it reads `ctx.model` which calls `getModel()` → returns `undefined`. The safeguard then returns a fallback summary with no actual content:
```
Summary unavailable due to context limits. Older messages were truncated.
```
This effectively **discards all conversation history** on every compaction. It also causes **cascading re-compactions**: the empty summary is only ~50 tokens, so the next tool call immediately fills the context again, triggering another compaction, which again produces an empty summary.
In a single session I observed **22 consecutive compactions**, all with empty summaries.
## Root Cause
`ExtensionRunner.getModel` defaults to `() => undefined` and is only set to the correct getter during `initialize()`. The three built-in pi-coding-agent modes (interactive, print, rpc) all call `initialize()`, but Clawdbot's embedded runner (`compact.js`, `run/attempt.js`) does not.
In `AgentSession._runAutoCompaction()`, the model and API key are correctly validated via `this.model` **before** emitting the `session_before_compact` event. So the model is available -- just not through the extension context's `ctx.model` getter.
## Fix
When `ctx.model` or `apiKey` is unavailable, return `undefined` instead of the fallback summary. This lets the built-in compaction code in `AgentSession` handle summarization, which correctly accesses the model via `this.model` (`agent.state.model`) and produces a proper summary.
## Alternative
The deeper fix would be to ensure `extensionRunner.initialize()` is called in the embedded runner flow, but that's a larger change. This fix is safe and minimal -- the built-in compaction path is well-tested and produces correct summaries.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR adjusts the `session_before_compact` compaction-safeguard extension so it no longer emits an “empty fallback” compaction result when `ctx.model` or its API key is unavailable (notably in embedded runner mode where `extensionRunner.initialize()` is not invoked). Instead it returns `undefined`, allowing `AgentSession`’s built-in compaction path to run with a valid model sourced from the session state, preventing repeated compactions caused by near-empty summaries.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Change is narrowly scoped to early-return behavior in the compaction safeguard; it removes a harmful fallback output in cases where the extension lacks model/apiKey context and defers to the core, already-validated compaction logic. No API surface changes, and failure path for real summarization errors is unchanged.
- No files require special attention
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#6108: Fix compaction producing empty summary when ctx.model is undefined ...
by GangEunzzang · 2026-02-01
90.6%
#12046: fix(compaction): add fallback for undefined ctx.model (#12016)
by anandsuraj · 2026-02-08
87.5%
#10711: fix: cancel compaction instead of truncating history when summariza...
by DukeDeSouth · 2026-02-06
81.0%
#17864: fix(compaction): pass model through runtime + reduce chunk ratio to...
by battman21 · 2026-02-16
81.0%
#8903: fix: improve compaction summary instructions to preserve active work
by joetomasone · 2026-02-04
79.5%
#9620: fix: increase auto-compaction reserve buffer to 40k tokens
by Arlo83963 · 2026-02-05
79.4%
#11089: feat(compaction): support customInstructions and model override for...
by p697 · 2026-02-07
79.2%
#5380: fix(compaction): include recent messages as fallback when summary u...
by Glucksberg · 2026-01-31
79.2%
#5360: fix(compaction): add emergency pruning for context overflow
by sgwannabe · 2026-01-31
78.3%
#18997: fix: improve context overflow error messages and docs
by realhoratiobot · 2026-02-17
77.9%