mastra-ai/mastra · error
Expected format azure-openai/deployment-name, but got ${rout
Error message
Expected format azure-openai/deployment-name, but got ${routerId} What it means
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.
Source
Thrown at packages/core/src/llm/model/gateway-resolver.ts:19
export type ResolvedModelConfig = {
url: string | false;
headers: Record<string, string>;
resolvedModelId: string;
fullModelId: string;
};
export function parseModelRouterId(routerId: string, gatewayPrefix?: string): { providerId: string; modelId: string } {
if (gatewayPrefix && !routerId.startsWith(`${gatewayPrefix}/`)) {
throw new Error(`Expected ${gatewayPrefix}/ in model router ID ${routerId}`);
}
const idParts = routerId.split('/');
// Azure OpenAI uses 2-part format (azure-openai/deployment), others use 3-part (gateway/provider/model)
if (gatewayPrefix === 'azure-openai') {
const modelId = idParts.slice(1).join('/');
if (!modelId) {
throw new Error(`Expected format azure-openai/deployment-name, but got ${routerId}`);
}
return {
providerId: 'azure-openai',
modelId, // Deployment name
};
}
// Provider-equals-gateway: a gateway whose provider id is the same as its
// gateway id (e.g. amazon-bedrock) uses a 2-part router id (gateway/model),
// because there is no separate provider segment to namespace. Catalog ids
// for such gateways are always two parts (model ids contain no slashes).
if (gatewayPrefix && idParts.length === 2 && idParts[0] === gatewayPrefix) {
const modelId = idParts[1];
if (!modelId) {
throw new Error(`Expected format ${gatewayPrefix}/model, but got ${routerId}`);
}
return {
providerId: gatewayPrefix,View on GitHub (pinned to 75dd419e61)
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.
Example fix
// before
parseModelRouterId(`azure-openai/${deployment}`, "azure-openai"); // deployment === ""
// after
if (!deployment) throw new Error("deployment is required");
parseModelRouterId(`azure-openai/${deployment}`, "azure-openai"); Defensive patterns
Strategy: validation
Validate before calling
const deployment = 'my-embedding-deployment';
if (!deployment) throw new Error('Azure deployment name is required');
const routerId = `azure-openai/${deployment}`;
parseModelRouterId(routerId, 'azure-openai'); Type guard
const isValidAzureRouterId = (id) => id.startsWith('azure-openai/') && id.length > 'azure-openai/'.length; Try / catch
try {
const { providerId, modelId } = parseModelRouterId(routerId, 'azure-openai');
} catch (e) {
if (e instanceof Error && e.message.includes('azure-openai/deployment-name')) {
console.error(`Azure router id needs a deployment name: "${routerId}"`);
} else throw e;
} Prevention
- 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.
When it happens
Trigger: parseModelRouterId("azure-openai/", "azure-openai") or parseModelRouterId("azure-openai", "azure-openai") — an id whose deployment segment is missing/empty.
Common situations: Deployment name field left blank in stored config; trailing slash without a name; template strings where the deployment variable was undefined/empty.
Related errors
- Linear project source id is invalid.
- Expected ${gatewayPrefix}/ in model router ID ${routerId}
- Expected format ${gatewayPrefix}/model, but got ${routerId}
- ${fieldPath} must be a non-negative number of milliseconds o
- ClaudeSDKAgent resumeData must include sessionId or continue
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/5a84fcac4c154821.
Report an issue: GitHub.