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
- Add an "id" field to every model entry in the provider config
- Check for YAML indentation mistakes that put id under the wrong object
- 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
- Use a schema validator (zod/arktype) on provider configs before registration
- Never build model entries by hand — map from a typed source list
- Lint YAML configs for key typos (name vs id)
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
- Provider ${providerName}, model ${modelDef.id}: no "api" spe
- Failed to load tree-sitter language: {err}
- Destination option ${key} must be a string
- Destination option ${key} must be a finite number
- Destination option ${key} must be a boolean
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/e9949b7006d9c855.
Report an issue: GitHub.