{"record":{"id":"cb73d6578b3f6406","repo":"mastra-ai/mastra","slug":"invalid-model-string-format-config-expected-cb73d6","errorCode":null,"errorMessage":"Invalid model string format: \"${config}\". Expected format: \"provider/model\"","messagePattern":"Invalid model string format: \"(.+?)\"\\. Expected format: \"provider/model\"","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/llm/model/embedding-router.ts","lineNumber":145,"sourceCode":"    let normalizedConfig: {\n      providerId: string;\n      modelId: string;\n      url?: string;\n      apiKey?: string;\n      headers?: Record<string, string>;\n    };\n\n    if (typeof config === 'string') {\n      // Parse provider/model or gateway/provider/model from string.\n      const parts = config.split('/');\n      if (parts[0] === MASTRA_GATEWAY_ID) {\n        if (parts.length < 3) {\n          throw new Error(`Invalid model string format: \"${config}\". Expected format: \"mastra/provider/model\"`);\n        }\n        normalizedConfig = { providerId: MASTRA_GATEWAY_ID, modelId: parts.slice(1).join('/') };\n      } else {\n        if (parts.length !== 2) {\n          throw new Error(`Invalid model string format: \"${config}\". Expected format: \"provider/model\"`);\n        }\n        const [providerId, modelId] = parts as [string, string];\n        normalizedConfig = { providerId, modelId };\n      }\n    } else if ('providerId' in config && 'modelId' in config) {\n      normalizedConfig = {\n        providerId: config.providerId,\n        modelId: config.modelId,\n        url: config.url,\n        apiKey: config.apiKey,\n        headers: config.headers,\n      };\n    } else {\n      // config has 'id' field\n      const parts = config.id.split('/');\n      if (parts[0] === MASTRA_GATEWAY_ID) {\n        if (parts.length < 3) {\n          throw new Error(`Invalid model string format: \"${config.id}\". Expected format: \"mastra/provider/model\"`);","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/llm/model/embedding-router.ts#L127-L163","documentation":"The EmbeddingRouter constructor parses a model string that must be exactly two slash-separated segments: \"provider/model\" (e.g. \"openai/text-embedding-3-small\"). If the string contains more than 2 parts (or fewer), and is not a \"mastra/...\" gateway id, the constructor cannot determine providerId and modelId, so it throws. This fail-fast validation prevents ambiguous provider/model resolution later.","triggerScenarios":"new EmbeddingRouter({ id: ... }) or string config with a model id containing extra slashes, e.g. \"openai/models/text-embedding-3-small\" or a full gateway string \"mastra/openai/text-embedding\" passed where only \"provider/model\" is accepted.","commonSituations":"Developers copy a mastra gateway-style model string (3 parts) into an API expecting provider/model; model names containing slashes (Azure deployments, Hugging Face repo paths) pasted without the correct gateway prefix; typos adding an extra '/' segment.","solutions":["Change the string to exactly two segments: \"provider/model\" (e.g. \"openai/text-embedding-3-small\").","If you intended to use the Mastra gateway, prefix with \"mastra/\": \"mastra/provider/model\".","If the model id itself contains slashes, pass an object config { providerId, modelId } instead of a slash-delimited string.","Trim stray slashes or whitespace around the config string before constructing."],"exampleFix":"// before\nnew EmbeddingRouter(\"openai/org/models/text-embedding-3-small\");\n// after\nnew EmbeddingRouter(\"openai/text-embedding-3-small\");\n// or for slashed model ids:\nnew EmbeddingRouter({ providerId: \"openai\", modelId: \"org/models/text-embedding-3-small\" });","handlingStrategy":"validation","validationCode":"function isValidProviderModelString(s) {\n  const parts = s.split('/');\n  return parts.length === 2 && parts.every((p) => p.length > 0);\n}\nif (!isValidProviderModelString(config)) {\n  throw new TypeError(`Expected \"provider/model\", got: ${config}`);\n}","typeGuard":"function isProviderModel(s) {\n  const parts = s.split('/');\n  return parts.length === 2 && parts.every((p) => p.length > 0);\n}","tryCatchPattern":"let router;\ntry {\n  router = new EmbeddingRouter(config);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Invalid model string format')) {\n    console.error(`Bad model id \"${config}\": use \"provider/model\"`);\n    router = new EmbeddingRouter({ providerId: config.split('/')[0], modelId: config.split('/').slice(1).join('/') });\n  } else throw e;\n}","preventionTips":["Normalize config strings through a small helper that splits and re-validates segments before construction.","Prefer object config { providerId, modelId } when model ids may contain slashes.","Add a unit test per model id format your app persists."],"tags":["validation","configuration","model-router"],"backgroundTag":"invalid-model-string-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}