{"record":{"id":"e06953e2d652dd6d","repo":"n8n-io/n8n","slug":"invalid-model-id-rawid-expected-provider-mo","errorCode":null,"errorMessage":"Invalid model ID \"${rawId}\": expected \"provider/model-name\" format","messagePattern":"Invalid model ID \"(.+?)\": expected \"provider/model-name\" format","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/runtime/model/model-factory.ts","lineNumber":232,"sourceCode":"const SUPPORTED_PROVIDERS = Object.keys(LANGUAGE_PROVIDERS).join(', ');\n\n/**\n * Provider packages are loaded dynamically via require() so only the\n * provider needed at runtime must be installed.\n */\nexport function createModel(config: ModelConfig, fetch?: FetchFn): LanguageModel {\n\tif (isLanguageModel(config)) {\n\t\treturn config;\n\t}\n\n\tconst rawId = typeof config === 'string' ? config : config.id;\n\tif (!rawId || rawId.trim() === '') {\n\t\tthrow new Error('Model ID is required');\n\t}\n\n\tconst slashIndex = rawId.indexOf('/');\n\tif (slashIndex <= 0) {\n\t\tthrow new Error(`Invalid model ID \"${rawId}\": expected \"provider/model-name\" format`);\n\t}\n\tconst provider = rawId.slice(0, slashIndex) as ProviderId;\n\tconst modelName = rawId.slice(slashIndex + 1);\n\n\tconst entry = LANGUAGE_PROVIDERS[provider];\n\tif (!entry) {\n\t\tthrow new Error(\n\t\t\t`Unsupported provider: \"${provider}\". Supported providers: ${SUPPORTED_PROVIDERS}`,\n\t\t);\n\t}\n\n\t// Collect credential fields: strip `id`, pass the rest to Zod validation.\n\tlet credFields: Record<string, unknown> = {};\n\tif (typeof config !== 'string') {\n\t\tconst { id: _id, ...rest } = config as { id: string; [k: string]: unknown };\n\t\tcredFields = rest;\n\t}\n\t// Host configs (e.g. Instance AI's `{ id, url }` for OpenAI-compatible","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/runtime/model/model-factory.ts#L214-L250","documentation":"`createModel` requires the model ID in `\"provider/model-name\"` format — the slash separates the provider key from the model name. It throws when there is no slash (`slashIndex === -1`) or the slash is at position 0 (`slashIndex <= 0`), meaning the provider portion is empty. Both the provider segment and the model-name segment must be non-empty.","triggerScenarios":"Calling `createModel('claude-sonnet-4-5')` (no provider prefix), `createModel('/gpt-4o')` (empty provider), or `createModel({ id: 'gpt-4o' })`. Any ID lacking a `provider/` prefix triggers this.","commonSituations":"The user entered a bare model name without the provider prefix. A config migration stripped the provider segment. The model field in a UI accepted a bare name. Confusion between OpenAI-style model names (`gpt-4o`) and the required `openai/gpt-4o` format.","solutions":["Check the raw model ID string — it must contain a `/` with a non-empty provider before it.","Prefix the model name with the correct provider: `openai/gpt-4o`, `anthropic/claude-sonnet-4-5`, `google/gemini-1.5-pro`, etc.","Add input validation in the config/UI layer to enforce the `provider/model` format with a regex before saving.","If migrating from a bare-name config, write a migration that maps known model names to their `provider/name` form."],"exampleFix":"// before:\ncreateModel('claude-sonnet-4-5');\n\n// after:\ncreateModel('anthropic/claude-sonnet-4-5');","handlingStrategy":"validation","validationCode":"const MODEL_ID_PATTERN = /^[a-zA-Z0-9-]+\\/.+$/;\n\nfunction validateModelIdFormat(id: string): void {\n  if (!MODEL_ID_PATTERN.test(id)) {\n    throw new Error(`Model ID \"${id}\" must be in \"provider/model-name\" format`);\n  }\n}\n\nvalidateModelIdFormat(config.modelId);\nconst model = createModel(config.modelId);","typeGuard":"function isProviderModelFormat(id: string): boolean {\n  const slashIndex = id.indexOf('/');\n  return slashIndex > 0 && slashIndex < id.length - 1;\n}","tryCatchPattern":null,"preventionTips":["Validate the `provider/model` format with a regex in the config layer.","Show a format hint in the UI: 'Enter as provider/model-name (e.g. openai/gpt-4o)'.","Write a migration that prefixes bare model names with a provider for legacy configs."],"tags":["model-config","validation","format","provider"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}