can1357/oh-my-pi · error · Error

No API key for ${nextModel.provider}/${nextModel.id}

Error message

No API key for ${nextModel.provider}/${nextModel.id}

What it means

#cycleAvailableModel advances to the next model in the available list and resolves an API key via getApiKey before committing the switch; if no key resolves it throws. Cycling must only land on models the session can actually run, so unauthenticated neighbors in the cycle list are rejected with this error.

Source

Thrown at packages/coding-agent/src/session/model-controls.ts:464

		return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
	}

	async #cycleAvailableModel(direction: "forward" | "backward"): Promise<ModelCycleResult | undefined> {
		const previousEditMode = this.#host.resolveActiveEditMode();
		const availableModels = this.#host.modelRegistry.getAvailable();
		if (availableModels.length <= 1) return undefined;

		const currentModel = this.#model;
		let currentIndex = availableModels.findIndex(m => modelsAreEqual(m, currentModel));

		if (currentIndex === -1) currentIndex = 0;
		const len = availableModels.length;
		const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
		const nextModel = availableModels[nextIndex];

		const apiKey = await this.#host.modelRegistry.getApiKey(nextModel, this.#host.sessionId());
		if (!apiKey) {
			throw new Error(`No API key for ${nextModel.provider}/${nextModel.id}`);
		}

		this.#host.modelRegistry.clearSuppressedSelector(formatModelStringWithRouting(nextModel));
		this.#host.clearActiveRetryFallback();
		await this.#host.setModelWithProviderSessionReset(nextModel);
		this.#host.sessionManager.appendModelChange(`${nextModel.provider}/${nextModel.id}`);
		this.#host.settings.getStorage()?.recordModelUsage(`${nextModel.provider}/${nextModel.id}`);
		// Re-apply the current thinking level (or auto) for the newly selected model
		this.#reapplyThinkingLevel();
		await this.#host.syncAfterModelChange(previousEditMode);

		return { model: nextModel, thinkingLevel: this.thinkingLevel, isScoped: false };
	}

	/**
	 * Get all available models with valid API keys, filtered by `enabledModels` when configured.
	 * See {@link filterAvailableModelsByEnabledPatterns} for supported pattern forms and limitations.
	 */

View on GitHub (pinned to 9690622007)

Solutions

  1. Configure API keys for all providers present in the cycle list, or trim the list to authenticated providers
  2. Manually select a specific authenticated model instead of cycling
  3. Pre-filter the available model list with hasConfiguredAuth/getApiKey so cycles only include usable models
  4. Catch the error in the cycle handler and skip to the next candidate

Example fix

// before
await controls.cycleModel("forward"); // may land on unkeyed model
// after
const usable = models.filter(m => host.modelRegistry.hasConfiguredAuth(m));
// cycle within `usable` only
Defensive patterns

Strategy: fallback

Validate before calling

const cycleModels = allModels.filter(m =>
  registry.hasConfiguredAuth(m) || Boolean(await registry.getApiKey(m, sessionId)),
);

Try / catch

try {
  await controls.cycleModel("forward");
} catch (err) {
  if (err instanceof Error && err.message.startsWith("No API key for")) {
    await controls.cycleModel("forward"); // skip unkeyed neighbor
  } else throw err;
}

Prevention

When it happens

Trigger: Calling cycleModel (forward/backward) where availableModels[nextIndex] has no API key for the current session.

Common situations: Tab/keyboard cycling through models spanning multiple providers where only some providers have keys; using a curated model list that includes unconfigured providers; key removed mid-session.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


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