can1357/oh-my-pi · error · Error
/compact ${compactMode.name} does not take focus instruction
Error message
/compact ${compactMode.name} does not take focus instructions. What it means
Thrown by SessionMaintenance's compaction entrypoint when a compaction mode whose `rejectsFocus` flag is true (only `snapcompact`) is invoked together with focus instructions, either as custom text or via `options.internalGuidance`. snapcompact archives history into bitmap images without producing an LLM summary, so focus text would be silently dropped; the library refuses rather than ignore it. The slash-command path pre-validates via `parseCompactArgs`, so this mainly guards programmatic/SDK callers and the snapcompact fallback path (issue #4359).
Source
Thrown at packages/coding-agent/src/session/session-maintenance.ts:731
methodOffset = 0,
retryController?: AbortController,
): Promise<CompactionResult> {
const ownsCompactionController = retryController === undefined;
if (this.#compactionAbortController && this.#compactionAbortController !== retryController) {
throw new Error("Compaction already in progress");
}
// Resolve the `/compact <mode>` subcommand up front so input validation
// runs before we disconnect/abort the active agent operation below.
const compactMode = options?.mode ? findCompactMode(options.mode) : undefined;
// Modes that produce no LLM summary (snapcompact) have nothing to focus.
// Reject focus text loudly so programmatic callers don't silently lose
// instructions (the slash path pre-validates via parseCompactArgs).
// `internalGuidance` counts the same way — plan-mode approval never
// combines with a rejects-focus mode, but reject early if a caller ever
// wires it up so we don't silently drop the directive on the snapcompact
// fallback (issue #4359).
if (compactMode?.rejectsFocus && (customInstructions || options?.internalGuidance)) {
throw new Error(`/compact ${compactMode.name} does not take focus instructions.`);
}
let methods: CompactionMethod[] = [];
let selectedMethodIndex = -1;
let compactionCommitted = false;
let methodAttempted = false;
const compactionAbortController = retryController ?? new AbortController();
const manualCompactionCleanup = ownsCompactionController ? Promise.withResolvers<void>() : undefined;
if (ownsCompactionController) {
this.#compactionAbortController = compactionAbortController;
this.#manualCompactionCleanup = manualCompactionCleanup?.promise;
}
// A manual pass supersedes any background speculation; running both would
// double-bill the summarizer and race the commit.
this.cancelSpeculation();
try {
if (ownsCompactionController) {
this.#host.disconnectFromAgent();View on GitHub (pinned to 9690622007)
Solutions
- Remove the custom instructions / internalGuidance when the mode is snapcompact.
- Switch the mode to `soft` or `remote` if you actually want directed focus text.
- If an extension injects internalGuidance unconditionally, gate it on `!compactMode?.rejectsFocus` before calling.
Example fix
// before
await session.compact({ mode: "snapcompact" }, "focus on auth changes");
// after
await session.compact({ mode: "snapcompact" }); // snapcompact takes no focus text Defensive patterns
Strategy: validation
Validate before calling
import { findCompactMode } from "./compact-modes";
const modeDef = compactMode ? findCompactMode(compactMode.name) : undefined;
if (modeDef?.rejectsFocus && (customInstructions || options?.internalGuidance)) {
throw new Error(`${modeDef.name} does not accept focus instructions`);
} Type guard
function takesFocus(mode?: { name: string; rejectsFocus?: boolean }): boolean {
return !mode?.rejectsFocus;
} Prevention
- Check `CompactModeDef.rejectsFocus` before attaching instructions to a compaction call.
- Prefer the slash path (`parseCompactArgs`) which pre-validates this combination.
- Never wire internalGuidance unconditionally across all compaction modes.
When it happens
Trigger: Calling the compaction API with `compactMode` set to a mode where `CompactModeDef.rejectsFocus === true` (snapcompact) while passing non-empty `customInstructions` or `options.internalGuidance`. E.g. `session.compact({ mode: 'snapcompact' }, 'focus on the refactor plan')` from an extension or SDK script.
Common situations: Extensions that attach `internalGuidance` for plan-mode approval wiring it up for every compaction call; scripts porting a `/compact snapcompact focus text` invocation after the parser began rejecting it; mixing snapcompact with prompt-directive logic written for the soft/remote modes.
Related errors
- 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
- 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/d617b8a5c89cac46.
Report an issue: GitHub.