can1357/oh-my-pi · error

snapcompact shape was not resolved before rendering.

Error message

snapcompact shape was not resolved before rendering.

What it means

An internal invariant error: snapcompact reached the rendering step (`snapcompact.compact`) but the pre-computed `snapcompactShape` is undefined. The shape (conversation layout: frames, dimensions, kept-message split) must be resolved before rendering; a null here means an earlier resolution step was skipped or failed silently. This indicates a bug or a mis-wired custom path, not user error.

Source

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

			// 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,
						});
						this.#host.emitNotice(
							"warning",
							"snapcompact produced too much standing image payload.",

View on GitHub (pinned to 9690622007)

Solutions

  1. Retry the compaction — if transient (abort during shape resolution), a fresh run should resolve the shape.
  2. Ensure the full snapcompact pipeline (shape resolution, then compact) is used rather than calling the render step directly.
  3. If reproducible on an unmodified install, report a bug with the settings and session characteristics.

Example fix

// before
const result = await snapcompact.compact(preparation, { model }); // shape never resolved
// after
const shape = snapcompact.resolveShape(preparation, { model });
const result = await snapcompact.compact(preparation, { model, shape });
Defensive patterns

Strategy: retry

Type guard

function shapeResolved(shape: SnapcompactShape | undefined): shape is SnapcompactShape {
  return shape != null;
}
if (!shapeResolved(snapcompactShape)) throw new Error("resolve shape before rendering");

Try / catch

try {
  await session.compact({ mode: "snapcompact" });
} catch (err) {
  if (err instanceof Error && err.message.includes("shape was not resolved")) {
    await Bun.sleep(100);
    return session.compact({ mode: "snapcompact" }); // transient abort during resolution
  }
  throw err;
}

Prevention

When it happens

Trigger: A code path invoking the snapcompact render step without first running shape resolution (the step that computes kept-history fit and frame layout); settings combinations that skip resolution (e.g. snapcompactShape resolution gated behind a branch that doesn't run); upgrades where resolution moved but a caller wasn't updated.

Common situations: Custom forks/patches to compaction flow; extension or SDK callers reimplementing the snapcompact pipeline and skipping a step; race where shape resolution was aborted (e.g. by the compaction abort controller) but rendering continued.

Related errors


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