can1357/oh-my-pi · error

Provider ${providerName}: must specify "baseUrl", "headers",

Error message

Provider ${providerName}: must specify "baseUrl", "headers", "apiKey", "auth: none", "compat", "disableStrictTools", "guardrailIdentifier", "remoteCompaction", "modelOverrides", "discovery", or "models"

What it means

validateProviderConfiguration rejects a provider entry that is effectively empty: in models-config mode with no `models` array, the config must contribute at least one meaningful setting (baseUrl, headers, apiKey, auth:none, compat, disableStrictTools, guardrailIdentifier, remoteCompaction, modelOverrides, or discovery). A provider stanza that sets none of these has nothing to apply and is rejected rather than silently ignored.

Source

Thrown at packages/coding-agent/src/config/models-config.ts:59

	const hasProviderApi = !!config.api;
	const models = config.models;

	if (models.length === 0) {
		if (mode === "models-config") {
			const hasModelOverrides = config.modelOverrides && Object.keys(config.modelOverrides).length > 0;
			if (
				!config.baseUrl &&
				!config.headers &&
				!config.compat &&
				!config.apiKey &&
				config.auth !== "none" &&
				!config.disableStrictTools &&
				!config.guardrailIdentifier &&
				!config.remoteCompaction &&
				!hasModelOverrides &&
				!config.discovery
			) {
				throw new Error(
					`Provider ${providerName}: must specify "baseUrl", "headers", "apiKey", "auth: none", "compat", "disableStrictTools", "guardrailIdentifier", "remoteCompaction", "modelOverrides", "discovery", or "models"`,
				);
			}
		}
	} else {
		if (!config.baseUrl) {
			throw new Error(`Provider ${providerName}: "baseUrl" is required when defining custom models.`);
		}
		const requiresAuth =
			mode === "runtime-register"
				? !config.apiKey && !config.oauthConfigured
				: !config.apiKey && (config.auth ?? "apiKey") !== "none" && (config.auth ?? "apiKey") !== "oauth";
		if (requiresAuth) {
			throw new Error(
				mode === "runtime-register"
					? `Provider ${providerName}: "apiKey" or "oauth" is required when defining models.`
					: `Provider ${providerName}: "apiKey" is required when defining custom models unless auth is "none" or "oauth".`,
			);

View on GitHub (pinned to 9690622007)

Solutions

  1. Add the intended setting — most commonly `baseUrl` plus `apiKey` — to the provider stanza.
  2. If the provider was a leftover placeholder, delete the stanza entirely.
  3. If you only wanted global tweaks, use the correct key (compat, modelOverrides, disableStrictTools, etc.) recognized by the schema.

Example fix

// before (models.json)
"providers": { "mygw": {} }
// after
"providers": { "mygw": { "baseUrl": "https://gw.example.com/v1", "apiKey": "sk-...", "models": [{ "id": "mini" }] } }
Defensive patterns

Strategy: validation

Validate before calling

function providerStanzaMeaningful(cfg: Record<string, unknown>): boolean {
  const keys = ["baseUrl", "headers", "apiKey", "auth", "compat", "disableStrictTools", "guardrailIdentifier", "remoteCompaction", "modelOverrides", "discovery", "models"];
  return keys.some(k => cfg[k] !== undefined);
}

Type guard

function isConfigurableProvider(cfg: object): cfg is { baseUrl: string } & Record<string, unknown> {
  return "baseUrl" in cfg || "models" in cfg || "discovery" in cfg;
}

Try / catch

try {
  modelsConfig.apply(parsed);
} catch (err) {
  if (err instanceof Error && err.message.includes('must specify "baseUrl"')) {
    const provider = err.message.match(/Provider ([^:]+):/)?.[1];
    logger.warn(`Provider ${provider} stanza is empty; removing or filling it required`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Defining a provider in models.json / the models config file (via ModelsConfigFile, or indirectly through registerProvider) with only a name — e.g. `{ "providers": { "mygw": {} } }` or a stanza containing only unrelated keys like `name`/`description`.

Common situations: Hand-editing models.json and leaving a placeholder provider; deleting the baseUrl line while keeping the provider block; migrating configs where the old key names were dropped by a schema change, leaving an empty stanza.

Related errors


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