can1357/oh-my-pi · error

Provider ${providerName}: model missing "id"

Error message

Provider ${providerName}: model missing "id"

What it means

Thrown by validateProviderConfiguration when a model definition in a provider's models array has no "id" field. The id is the model's identity used for routing requests, catalog lookup, and display, so a model without one cannot be registered. Unlike the api check, this applies in both runtime-register and models-config modes.

Source

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

					: `Provider ${providerName}: "apiKey" is required when defining custom models unless auth is "none" or "oauth".`,
			);
		}
	}

	if (mode === "models-config" && config.discovery && !config.api && config.discovery.type !== "proxy") {
		throw new Error(`Provider ${providerName}: "api" is required when discovery is enabled at provider level.`);
	}

	for (const modelDef of models) {
		if (!hasProviderApi && !modelDef.api) {
			throw new Error(
				mode === "runtime-register"
					? `Provider ${providerName}, model ${modelDef.id}: no "api" specified.`
					: `Provider ${providerName}, model ${modelDef.id}: no "api" specified. Set at provider or model level.`,
			);
		}
		if (!modelDef.id) {
			throw new Error(`Provider ${providerName}: model missing "id"`);
		}
		if (mode === "models-config") {
			if (modelDef.contextWindow !== undefined && modelDef.contextWindow <= 0) {
				throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid contextWindow`);
			}
			if (modelDef.maxTokens !== undefined && modelDef.maxTokens <= 0) {
				throw new Error(`Provider ${providerName}, model ${modelDef.id}: invalid maxTokens`);
			}
		}
	}
}

export const ModelsConfigFile = new ConfigFile<ModelsConfig>("models", {
	kind: "deferred",
	resolve: getModelsConfigSchema,
}).withValidation("models", config => {
	const providers = config.providers ?? {};
	for (const providerName in providers) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Add an "id" field to every model entry in the provider config
  2. Check for YAML indentation mistakes that put id under the wrong object
  3. Validate your models-config JSON/YAML against the schema before loading

Example fix

// before
{ "models": [{ "name": "gpt-x", "api": "openai-completions" }] }
// after
{ "models": [{ "id": "gpt-x", "api": "openai-completions" }] }
Defensive patterns

Strategy: validation

Validate before calling

function assertModelIds(cfg) {
  (cfg.models ?? []).forEach((m, i) => {
    if (typeof m.id !== 'string' || !m.id) throw new Error(`models[${i}].id missing`);
  });
}

Type guard

function hasId(m) { return typeof m === 'object' && m !== null && typeof m.id === 'string' && m.id.length > 0; }

Try / catch

try { registerProvider(cfg); } catch (e) { if (String(e).includes('model missing "id"')) { logger.error('Every model entry needs an id', { provider: cfg.name }); } else throw e; }

Prevention

When it happens

Trigger: registerProvider called with a models array containing an entry missing id; models-config file parsed with a model object lacking the id key.

Common situations: YAML/JSON typo ("model" instead of "id"), copy-paste of a model entry where the id line was deleted, programmatically generated model lists where an empty/anonymous object slipped in.

Related errors


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