can1357/oh-my-pi · info · CompactionCancelledError
Compaction cancelled
Error message
Compaction cancelled
What it means
A `CompactionCancelledError` thrown when a `session.before_compact` extension hook returns `{ cancel: true }`, aborting the compaction before it runs. Extensions use this to veto compaction (e.g. to defer it or handle context pressure differently); the error propagates so callers know compaction did not happen by deliberate cancellation, not failure.
Source
Thrown at packages/coding-agent/src/session/session-maintenance.ts:836
}
throw new Error("Nothing to compact (session too small)");
}
let hookCompaction: CompactionResult | undefined;
let fromExtension = false;
let preserveData: Record<string, unknown> | undefined;
if (this.#host.extensionRunner?.hasHandlers("session_before_compact")) {
const result = (await this.#host.extensionRunner.emit({
type: "session_before_compact",
preparation,
branchEntries: pathEntries,
customInstructions,
signal: compactionAbortController.signal,
})) as SessionBeforeCompactResult | undefined;
if (result?.cancel) {
throw new CompactionCancelledError();
}
if (result?.compaction) {
hookCompaction = result.compaction;
fromExtension = true;
}
}
const compactionPrep = await this.#prepareCompactionFromHooks(preparation, hookCompaction);
if (compactionPrep.kind !== "fromHook") methodAttempted = true;
// Focus instructions require an LLM summary, so the preference resolver
// only selects snapcompact for an undirected manual compaction.
const wantsSnapcompact = compactionPrep.kind !== "fromHook" && selectedMethod === "snapcompact";
const snapcompactReady = wantsSnapcompact;
const snapcompactShapeSetting = this.#host.settings.get("snapcompact.shape");
let snapcompactShape: snapcompact.Shape | undefined;
// Claude refuses inputs that reproduce its own reasoning as textView on GitHub (pinned to 9690622007)
Solutions
- Identify the extension registering a before_compact hook and check why it cancels; disable it if unwanted.
- Catch CompactionCancelledError separately and treat it as a benign, intentional abort.
- If the extension should replace rather than cancel, let its `result.compaction` path supply a compaction result instead.
Example fix
// before
try { await session.compact(); } catch (e) { report(e); }
// after
try { await session.compact(); }
catch (e) {
if (e instanceof CompactionCancelledError) return; // extension vetoed
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const handler = (e) => e.type === "before_compact" ? { cancel: false } : undefined; // audit installed extensions that register before_compact hooks Try / catch
import { CompactionCancelledError } from "./compaction-errors";
try {
await session.compact();
} catch (err) {
if (err instanceof CompactionCancelledError) return; // intentional extension veto
throw err;
} Prevention
- Audit installed extensions for before_compact hooks when compaction unexpectedly aborts.
- Handle CompactionCancelledError as a distinct, benign outcome in callers.
- Extensions should return a compaction result (result.compaction) instead of plain cancel when they replace the flow.
When it happens
Trigger: Any installed extension implementing the `before_compact` hook returning `cancel: true` — commonly when the extension's own logic decides context is fine, or when it wants to run a custom compaction and cancel the built-in one.
Common situations: Context-management extensions (custom summarizers, memory tools) installed by the user; a hook crashing-but-catching into a cancel; recently installed extension the user forgot about, making /compact mysteriously abort.
Related errors
- Model ${model.id} does not support V2 streaming compaction
- V2 remote compaction failed (${response.status} ${response.s
- No response body for V2 compaction streaming
- V2 compaction stream closed before response.completed
- V2 compaction expected exactly one compaction output item, g
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5b878e3cbe18fd60.
Report an issue: GitHub.