can1357/oh-my-pi · error
snapcompact cannot run locally: ${this.#model.id} is text-on
Error message
snapcompact cannot run locally: ${this.#model.id} is text-only. What it means
Thrown when snapcompact is selected but the active model's declared inputs do not include `image`. snapcompact archives history into dense bitmap images the model must read back, so it fundamentally requires a vision-capable model; with a text-only model it cannot run and the library fails fast after emitting a warning notice.
Source
Thrown at packages/coding-agent/src/session/session-maintenance.ts:865
// 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
// ("reasoning_extraction"), and the snapcompact archive is replayed as
// text into every later request; drop `¶think:` sections for
// Anthropic-dialect targets (issue #6093).
const snapcompactIncludeThinking = preferredDialect(this.#model.id) !== "anthropic";
if (wantsSnapcompact && !this.#model.input.includes("image")) {
this.#host.emitNotice(
"warning",
`snapcompact needs a vision-capable model (${this.#model.id} is text-only)`,
"compaction",
);
throw new Error(`snapcompact cannot run locally: ${this.#model.id} is text-only.`);
} else if (snapcompactReady) {
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",View on GitHub (pinned to 9690622007)
Solutions
- Select a vision-capable model (input includes "image") before running snapcompact.
- Use `/compact soft` or `/compact remote` instead, which summarize as text.
- If the model actually supports images, fix the model metadata (catalog/discovery) so `input` lists "image".
Example fix
// before
await session.compact({ mode: "snapcompact" }); // text-only model
// after
await session.setModel("google/gemini-2.5-flash"); // vision-capable
await session.compact({ mode: "snapcompact" }); Defensive patterns
Strategy: validation
Validate before calling
const model = session.getModel();
if (mode === "snapcompact" && model && !model.input.includes("image")) {
throw new Error(`snapcompact needs a vision-capable model (${model.id} is text-only)`);
} Type guard
function isVisionCapable(model: { input: string[] }): boolean {
return model.input.includes("image");
} Try / catch
try {
await session.compact({ mode: "snapcompact" });
} catch (err) {
if (err instanceof Error && err.message.includes("snapcompact cannot run locally")) {
return session.compact({ mode: "soft" }); // text-summary fallback
}
throw err;
} Prevention
- Check `model.input` for "image" before choosing snapcompact.
- Pick a vision-capable default model if snapcompact is your standard flow.
- Distrust modality metadata for new models — verify vision support with a probe.
When it happens
Trigger: Running `/compact snapcompact` (or the snapcompact method via methodOrder) while the selected model has `input` metadata lacking "image" — e.g. a text-only model like an older or reasoning-only variant.
Common situations: Switching to a text-only model then using a saved snapcompact default; discovery metadata misreporting modality so the user believes the model supports images; hardcoded snapcompact in scripts after switching providers.
Related errors
- /compact ${compactMode.name} does not take focus instruction
- snapcompact cannot render this conversation locally: unsuppo
- snapcompact cannot run locally: kept history alone exceeds t
- snapcompact shape was not resolved before rendering.
- Model ${model.id} does not support V2 streaming compaction
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/361091a20f9c16e6.
Report an issue: GitHub.