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
- Retry the compaction — if transient (abort during shape resolution), a fresh run should resolve the shape.
- Ensure the full snapcompact pipeline (shape resolution, then compact) is used rather than calling the render step directly.
- 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
- Use the full built-in snapcompact pipeline; never call the render step directly.
- Check compaction abort signals between shape resolution and rendering.
- Report persistent occurrences on unmodified installs as a bug.
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
- /compact ${compactMode.name} does not take focus instruction
- snapcompact cannot run locally: ${this.#model.id} is text-on
- snapcompact cannot render this conversation locally: unsuppo
- snapcompact cannot run locally: kept history alone exceeds t
- Internal daemon result ${result.op} is not tool-visible
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/862860778903d402.
Report an issue: GitHub.