can1357/oh-my-pi · warning · Error
Compaction already in progress
Error message
Compaction already in progress
What it means
SessionMaintenance serializes compactions with a single #compactionAbortController. When a new compaction request starts while another is already running (and the caller did not pass the existing retryController), it throws 'Compaction already in progress'. Only one compaction may run per session at a time.
Source
Thrown at packages/coding-agent/src/session/session-maintenance.ts:718
return undefined;
}
}
/**
* Manually compact the session context.
* Aborts current agent operation first.
* @param customInstructions Optional instructions for the compaction summary
* @param options Optional callbacks for completion/error handling
*/
async compact(
customInstructions?: string,
options?: CompactOptions,
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;View on GitHub (pinned to 9690622007)
Solutions
- Wait for the in-flight compaction to finish before starting another (await its promise or listen for completion)
- Skip the new request if compaction is already active (query maintenance state first)
- Queue or coalesce compaction requests instead of issuing them concurrently
- If stale state persists with no compaction actually running, reset the session/maintenance state (bug) and file an issue
Example fix
// before
await session.compact(); // throws if one is running
// after
if (!maintenance.isCompacting()) {
await session.compact();
} else {
await maintenance.waitForCompaction();
} Defensive patterns
Strategy: validation
Validate before calling
if (maintenance.isCompacting?.()) {
return; // or await the in-flight promise
}
await session.compact(options); Try / catch
try {
await session.compact(options);
} catch (err) {
if (err instanceof Error && err.message === "Compaction already in progress") {
await existingCompactionPromise; // coalesce instead of failing
} else throw err;
} Prevention
- Guard against concurrent compaction calls with a session-level flag
- Coalesce or queue compaction requests rather than issuing in parallel
- Disable manual /compact while auto-compaction runs
- Ensure error paths always clear the compaction controller so state never goes stale
When it happens
Trigger: Calling compact (or a compaction method) while this.#compactionAbortController is set and different from the provided retryController — i.e. a second concurrent compaction attempt.
Common situations: User runs /compact twice in quick succession; automatic context-window compaction triggers while a manual compaction is running; programmatic compaction racing a UI-initiated one; a previous compaction left the controller uncleared after a crash path.
Related errors
- No model selected for handoff
- No model selected
- Already compacted
- experiment ${id} has running arms (${live.map(r => r.jobName
- run ${jobName} is running; cancel it first
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/058c69a0ce6b0f3b.
Report an issue: GitHub.