can1357/oh-my-pi · error

snapcompact cannot run locally: kept history alone exceeds t

Error message

snapcompact cannot run locally: kept history alone exceeds the context budget.

What it means

Thrown when snapcompact computes that even the kept (recent) history alone exceeds the model's context budget — after excluding what gets archived to images, the retained messages already fill (or overflow) the context window, so rendering the archive on top cannot fit. snapcompact aborts and emits a warning notice instead of producing a request the model would reject.

Source

Thrown at packages/coding-agent/src/session/session-maintenance.ts:914

			let codexCompaction: CodexCompactionContext | undefined;

			// Snapcompact runs locally first. The frame cap is sized from the live
			// model window via #computeSnapcompactMaxFrames so the post-render context
			// fits without the warning loop (issue #3247). A local blocker rejects
			// this method, allowing the configured preference order to continue.
			let snapcompactResult: snapcompact.CompactionResult | undefined;
			if (snapcompactReady) {
				const maxFrames = this.#computeSnapcompactMaxFrames(preparation, effectiveSettings);
				if (maxFrames < 1) {
					logger.warn("Snapcompact skipped: kept history alone exceeds the context budget", {
						model: this.#model?.id,
					});
					this.#host.emitNotice(
						"warning",
						"snapcompact: kept history alone exceeds the context budget.",
						"compaction",
					);
					throw new Error("snapcompact cannot run locally: kept history alone exceeds the context budget.");
				} else {
					const shape = snapcompactShape;
					if (!shape) {
						throw new Error("snapcompact shape was not resolved before rendering.");
					}
					snapcompactResult = await snapcompact.compact(preparation, {
						convertToLlm,
						model: this.#model,
						...(snapcompactShapeSetting === "auto" ? {} : { shape }),
						maxFrames,
						includeThinking: snapcompactIncludeThinking,
					});
					const framePayloadBytes = this.#snapcompactFramePayloadBytes(snapcompactResult);
					if (framePayloadBytes > snapcompact.FRAME_DATA_BYTES_BUDGET) {
						logger.warn("Snapcompact exceeded the per-request frame payload budget", {
							model: this.#model?.id,
							framePayloadBytes,
							budget: snapcompact.FRAME_DATA_BYTES_BUDGET,

View on GitHub (pinned to 9690622007)

Solutions

  1. Run snapcompact earlier, before kept history grows past the budget.
  2. Switch to a larger-context model for this compaction.
  3. Remove or shrink oversized recent entries (e.g. huge tool outputs) from the session, or use a different compaction method that tolerates the load.

Example fix

// before
if (tokens > hardLimit) await session.compact({ mode: "snapcompact" }); // too late
// after
if (tokens > softLimit) await session.compact({ mode: "snapcompact" }); // compact earlier
Defensive patterns

Strategy: validation

Validate before calling

const usage = session.getTokenUsage();
const ctx = session.getModel().contextWindow;
if (usage.total > ctx * 0.6) {
  // kept history may already exceed the snapcompact budget — compact earlier or switch model
}

Try / catch

try {
  await session.compact({ mode: "snapcompact" });
} catch (err) {
  if (err instanceof Error && err.message.includes("exceeds the context budget")) {
    return session.compact({ mode: "soft" }); // tolerate heavier sessions
  }
  throw err;
}

Prevention

When it happens

Trigger: Running snapcompact on a session where the recent kept messages are themselves enormous (e.g. one giant tool result or file dump in recent turns) against a small-context model; very low context-window model selected; snapcompact invoked far too late (context already blown).

Common situations: Pasting massive logs/files shortly before compacting; a model switch to a smaller-context model mid-session; automation that only compacts after the first API overflow.

Related errors


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