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 text

View on GitHub (pinned to 9690622007)

Solutions

  1. Identify the extension registering a before_compact hook and check why it cancels; disable it if unwanted.
  2. Catch CompactionCancelledError separately and treat it as a benign, intentional abort.
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/5b878e3cbe18fd60. Report an issue: GitHub.