can1357/oh-my-pi · error

snapcompact cannot render this conversation locally: unsuppo

Error message

snapcompact cannot render this conversation locally: unsupported characters for selected snapcompact font (${percent}%).

What it means

Thrown when snapcompact's renderability probe finds too large a fraction of the conversation text cannot be rendered by the selected snapcompact bitmap font (unrenderable ratio above the configured limit). Because unrenderable characters would corrupt or blank out archived history images, snapcompact refuses to run rather than silently lose content. A warning notice with the exact percentage is emitted first.

Source

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

				const text = snapcompact.serializeConversation(
					convertToLlm(preparation.messagesToSummarize.concat(preparation.turnPrefixMessages)),
					{ includeThinking: snapcompactIncludeThinking },
				);
				const probeText = snapcompact.renderabilityProbeText(
					text,
					preparation.previousPreserveData,
					preparation.previousSummary,
				);
				snapcompactShape = snapcompact.resolveShapeForText(probeText, this.#model, snapcompactShapeSetting);
				const renderScan = snapcompact.scanRenderability(probeText, { shape: snapcompactShape });
				if (!renderScan.isSafe) {
					const percent = (renderScan.unrenderableRatio * 100).toFixed(1);
					this.#host.emitNotice(
						"warning",
						`snapcompact disabled: unsupported characters for selected snapcompact font (${percent}%).`,
						"compaction",
					);
					throw new Error(
						`snapcompact cannot render this conversation locally: unsupported characters for selected snapcompact font (${percent}%).`,
					);
				}
			}

			let summary: string;
			let shortSummary: string | undefined;
			let firstKeptEntryId: string;
			let tokensBefore: number;
			let details: unknown;
			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) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Configure a snapcompact font with wider glyph coverage for your content (compaction snapcompact settings).
  2. Fall back to a text summarization mode: `/compact soft` or `/compact remote`.
  3. Reduce non-renderable content (strip emoji/control chars from tool output) if you must use snapcompact.

Example fix

// before
await session.compact({ mode: "snapcompact" }); // CJK-heavy session
// after
await session.compact({ mode: "soft" }); // or set a CJK-capable snapcompact font
Defensive patterns

Strategy: fallback

Validate before calling

const probe = snapcompact.renderabilityProbeText(conversationText);
const ratio = snapcompact.unrenderableRatio(probe, font);
if (ratio > 0.05) useSnapcompact = false; // >5% unrenderable — use text summary

Try / catch

try {
  await session.compact({ mode: "snapcompact" });
} catch (err) {
  if (err instanceof Error && err.message.includes("unsupported characters")) {
    return session.compact({ mode: "soft" });
  }
  throw err;
}

Prevention

When it happens

Trigger: Running snapcompact on a conversation dense in characters outside the snapcompact font's coverage — CJK/emoji/heavy non-Latin text, unusual box-drawing/control characters in tool output, or a custom `compaction.snapcompactFont` setting with narrow glyph coverage.

Common situations: Sessions working mostly in Chinese/Japanese/Korean or with emoji-heavy logs; code reading binary-ish data printed into the transcript; a font setting changed/removed in an upgrade leaving a font that can't cover the session's script.

Related errors


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