{"record":{"id":"5a84fcac4c154821","repo":"mastra-ai/mastra","slug":"expected-format-azure-openai-deployment-name-but","errorCode":null,"errorMessage":"Expected format azure-openai/deployment-name, but got ${routerId}","messagePattern":"Expected format azure-openai/deployment-name, but got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/llm/model/gateway-resolver.ts","lineNumber":19,"sourceCode":"export type ResolvedModelConfig = {\n  url: string | false;\n  headers: Record<string, string>;\n  resolvedModelId: string;\n  fullModelId: string;\n};\n\nexport function parseModelRouterId(routerId: string, gatewayPrefix?: string): { providerId: string; modelId: string } {\n  if (gatewayPrefix && !routerId.startsWith(`${gatewayPrefix}/`)) {\n    throw new Error(`Expected ${gatewayPrefix}/ in model router ID ${routerId}`);\n  }\n\n  const idParts = routerId.split('/');\n\n  // Azure OpenAI uses 2-part format (azure-openai/deployment), others use 3-part (gateway/provider/model)\n  if (gatewayPrefix === 'azure-openai') {\n    const modelId = idParts.slice(1).join('/');\n    if (!modelId) {\n      throw new Error(`Expected format azure-openai/deployment-name, but got ${routerId}`);\n    }\n    return {\n      providerId: 'azure-openai',\n      modelId, // Deployment name\n    };\n  }\n\n  // Provider-equals-gateway: a gateway whose provider id is the same as its\n  // gateway id (e.g. amazon-bedrock) uses a 2-part router id (gateway/model),\n  // because there is no separate provider segment to namespace. Catalog ids\n  // for such gateways are always two parts (model ids contain no slashes).\n  if (gatewayPrefix && idParts.length === 2 && idParts[0] === gatewayPrefix) {\n    const modelId = idParts[1];\n    if (!modelId) {\n      throw new Error(`Expected format ${gatewayPrefix}/model, but got ${routerId}`);\n    }\n    return {\n      providerId: gatewayPrefix,","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/llm/model/gateway-resolver.ts#L1-L37","documentation":"Azure OpenAI router ids use a 2-part format \"azure-openai/deployment-name\" (the deployment name is the modelId). If the prefix check passes but everything after \"azure-openai/\" is empty, there is no deployment to resolve and the function throws.","triggerScenarios":"parseModelRouterId(\"azure-openai/\", \"azure-openai\") or parseModelRouterId(\"azure-openai\", \"azure-openai\") — an id whose deployment segment is missing/empty.","commonSituations":"Deployment name field left blank in stored config; trailing slash without a name; template strings where the deployment variable was undefined/empty.","solutions":["Provide the deployment name: \"azure-openai/your-deployment\".","Validate the deployment variable is non-empty before building the id.","Check for accidental trailing slashes when concatenating the id."],"exampleFix":"// before\nparseModelRouterId(`azure-openai/${deployment}`, \"azure-openai\"); // deployment === \"\"\n// after\nif (!deployment) throw new Error(\"deployment is required\");\nparseModelRouterId(`azure-openai/${deployment}`, \"azure-openai\");","handlingStrategy":"validation","validationCode":"const deployment = 'my-embedding-deployment';\nif (!deployment) throw new Error('Azure deployment name is required');\nconst routerId = `azure-openai/${deployment}`;\nparseModelRouterId(routerId, 'azure-openai');","typeGuard":"const isValidAzureRouterId = (id) => id.startsWith('azure-openai/') && id.length > 'azure-openai/'.length;","tryCatchPattern":"try {\n  const { providerId, modelId } = parseModelRouterId(routerId, 'azure-openai');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('azure-openai/deployment-name')) {\n    console.error(`Azure router id needs a deployment name: \"${routerId}\"`);\n  } else throw e;\n}","preventionTips":["Validate deployment names are non-empty when read from config/env/DB.","Avoid manual string concatenation that can leave a trailing slash with no name.","Pin Azure deployment names in typed config, not ad-hoc strings."],"tags":["parsing","azure","validation"],"backgroundTag":"invalid-model-string-format","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}