can1357/oh-my-pi · error · Error

No model selected

Error message

No model selected

What it means

Thrown when manual compaction starts but `this.#model` is unset, meaning no model has been selected for the session. Compaction needs an active model to resolve candidates, settings, and (for soft/snapcompact) to run. The library refuses to proceed with a null model rather than guessing one.

Source

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

		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();
				await this.#host.abort({ goalReason: "internal", preserveCompaction: true });
			}
			const activeModel = this.#model;
			if (!activeModel) {
				throw new Error("No model selected");
			}

			const compactionSettings = this.#host.settings.getGroup("compaction");
			methods = resolveCompactionMethodOrder(compactMode?.overrides.methodOrder ?? compactionSettings.methodOrder);
			const explicitSnapcompact = compactMode?.name === "snapcompact";
			let selectedMethod: CompactionMethod | undefined;
			for (let index = methodOffset; index < methods.length; index++) {
				const method = methods[index];
				if (method === "remote") {
					if (canUseRemoteCompaction(activeModel, resolveMethodSettings(compactionSettings, method))) {
						selectedMethod = method;
						selectedMethodIndex = index;
						break;
					}
					continue;
				}
				if (method === "snapcompact") {
					if (

View on GitHub (pinned to 9690622007)

Solutions

  1. Select a model first (e.g. `/model <provider/id>` in the CLI or the session's model-set API), then retry compaction.
  2. In SDK code, assert a model is set before calling compaction.
  3. Check earlier logs for a failed model-selection/provider-auth step that left the session without a model.

Example fix

// before
await session.compact(); // throws if no model
// after
if (!session.getModel()) await session.setModel("anthropic/claude-sonnet-4");
await session.compact();
Defensive patterns

Strategy: validation

Validate before calling

if (!session.getModel()) {
  throw new Error("Select a model before compacting");
}

Type guard

function hasModel(s: { getModel(): unknown | null }): boolean {
  return s.getModel() != null;
}

Try / catch

try {
  await session.compact();
} catch (err) {
  if (err instanceof Error && err.message === "No model selected") {
    await session.setModel(defaultModelId);
    await session.compact();
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Invoking compaction (manual `/compact` or API compaction call) on a session where `SessionMaintenance.#model` is still null — e.g. compaction before a model was ever set, or after the model was cleared without selecting a replacement.

Common situations: Running `/compact` in a fresh session before `/model` was used; SDK/embedding usage that calls compact() without first calling the model-selection API; automated flows where model selection failed earlier and the error was swallowed.

Related errors


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