can1357/oh-my-pi · error · Error

No API key for ${resolved.model.provider}/${resolved.model.i

Error message

No API key for ${resolved.model.provider}/${resolved.model.id}

What it means

Once the plan-YOLO target model resolves, main.ts checks `modelRegistry.hasConfiguredAuth(resolved.model)`. If no API key/credential is configured for that model's provider, it throws with `provider/id`. This fails fast at startup so YOLO mode never begins with a model it cannot call.

Source

Thrown at packages/coding-agent/src/main.ts:1280

		} else {
			options.prewalk = { target: resolved.model, thinkingLevel: resolved.thinkingLevel };
		}
	}

	if (parsed.planYoloInto !== undefined && !parsed.planYolo) {
		throw new Error("--plan-yolo-into requires --plan-yolo");
	}
	if (parsed.planYolo) {
		const rolePattern = expandRoleAlias(parsed.planYoloInto ?? "@smol", activeSettings);
		const resolved = resolveCliModel({ cliModel: rolePattern, modelRegistry, preferences: modelMatchPreferences });
		if (resolved.warning) {
			process.stderr.write(`${chalk.yellow(`Warning: ${resolved.warning}`)}\n`);
		}
		if (resolved.error || !resolved.model) {
			throw new Error(resolved.error ?? `Model "${parsed.planYoloInto ?? "@smol"}" not found`);
		}
		if (!modelRegistry.hasConfiguredAuth(resolved.model)) {
			throw new Error(`No API key for ${resolved.model.provider}/${resolved.model.id}`);
		}
		options.planYolo = { target: resolved.model, thinkingLevel: resolved.thinkingLevel };
	}

	// Thinking level
	if (parsed.thinking) {
		options.thinkingLevel = parsed.thinking;
	} else if (
		scopedModels.length > 0 &&
		scopedModels[0].explicitThinkingLevel === true &&
		// A deferred default role resolves its own model (and any explicit
		// thinking suffix) after extensions register; seeding the fallback
		// scoped model's level here would override it in createAgentSession.
		!deferredDefaultRole &&
		!restoringSession
	) {
		options.thinkingLevel = scopedModels[0].thinkingLevel;
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Set the API key for the resolved provider (e.g. export ANTHROPIC_API_KEY=... / OPENAI_API_KEY=...) or run the provider login flow.
  2. Point `--plan-yolo-into` at a model whose provider credentials you already have.
  3. Check provider configuration files/env in CI and add the missing secret.
  4. Re-authenticate if the stored credential expired.

Example fix

// before (no key configured)
omp --plan-yolo --plan-yolo-into @smol

// after
export ANTHROPIC_API_KEY=sk-ant-...
omp --plan-yolo --plan-yolo-into @smol
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight credential check per provider
if (!process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) {
  throw new Error("No provider API key configured; set ANTHROPIC_API_KEY or OPENAI_API_KEY");
}

Try / catch

try {
  await runOmp(["--plan-yolo", "--plan-yolo-into", "@smol"]);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("No API key for ")) {
    console.error("Configure credentials for the provider first (env var or login flow).");
  } else throw err;
}

Prevention

When it happens

Trigger: `--plan-yolo [--plan-yolo-into <model>]` resolving to a valid model whose provider has no credentials (no env var key, no auth.json entry, no OAuth login).

Common situations: Fresh machine without provider setup; targeting a provider you don't use (e.g. `@smol` alias points at a provider lacking a key); expired/rotated API key removed from config; CI lacking the secret env var.

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/bf75d3a6fbec2340. Report an issue: GitHub.