mastra-ai/mastra · error

Invalid model string format: "${config.id}". Expected format

Error message

Invalid model string format: "${config.id}". Expected format: "mastra/provider/model"

What it means

When config is an object with an `id` field whose first segment is "mastra", the EmbeddingRouter expects the Mastra gateway 3-part format "mastra/provider/model". If splitting on '/' yields fewer than 3 parts (e.g. just "mastra/model"), it throws, because the provider segment between the gateway prefix and model id is missing.

Source

Thrown at packages/core/src/llm/model/embedding-router.ts:163

          throw new Error(`Invalid model string format: "${config}". Expected format: "provider/model"`);
        }
        const [providerId, modelId] = parts as [string, string];
        normalizedConfig = { providerId, modelId };
      }
    } else if ('providerId' in config && 'modelId' in config) {
      normalizedConfig = {
        providerId: config.providerId,
        modelId: config.modelId,
        url: config.url,
        apiKey: config.apiKey,
        headers: config.headers,
      };
    } else {
      // config has 'id' field
      const parts = config.id.split('/');
      if (parts[0] === MASTRA_GATEWAY_ID) {
        if (parts.length < 3) {
          throw new Error(`Invalid model string format: "${config.id}". Expected format: "mastra/provider/model"`);
        }
        normalizedConfig = {
          providerId: MASTRA_GATEWAY_ID,
          modelId: parts.slice(1).join('/'),
          url: config.url,
          apiKey: config.apiKey,
          headers: config.headers,
        };
      } else {
        if (parts.length !== 2) {
          throw new Error(`Invalid model string format: "${config.id}". Expected format: "provider/model"`);
        }
        const [providerId, modelId] = parts as [string, string];
        normalizedConfig = {
          providerId,
          modelId,
          url: config.url,
          apiKey: config.apiKey,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use the full 3-part id: "mastra/provider/model" (e.g. "mastra/openai/text-embedding-3-small").
  2. If not using the Mastra gateway, drop the "mastra/" prefix and use "provider/model".
  3. Verify the id was not truncated during string interpolation or env-var loading.

Example fix

// before
new EmbeddingRouter({ id: "mastra/openai" });
// after
new EmbeddingRouter({ id: "mastra/openai/text-embedding-3-small" });
Defensive patterns

Strategy: validation

Validate before calling

function assertMastraId(id) {
  const parts = id.split('/');
  if (parts[0] === 'mastra' && parts.length < 3) {
    throw new Error(`Mastra ids need "mastra/provider/model", got: ${id}`);
  }
}
assertMastraId(config.id);

Type guard

const isMastraId = (id) => id.startsWith('mastra/') && id.split('/').length >= 3;

Try / catch

try {
  router = new EmbeddingRouter({ id });
} catch (e) {
  if (e instanceof Error && e.message.includes('mastra/provider/model')) {
    console.error(`Mastra gateway ids require 3 parts: ${id}`);
  } else throw e;
}

Prevention

When it happens

Trigger: new EmbeddingRouter({ id: "mastra/openai" }) or { id: "mastra" } — a mastra-prefixed id with no provider/model sub-path.

Common situations: Truncating a copied model id; assuming "mastra" alone selects the gateway without naming provider and model; programmatic string building that dropped a segment.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/5597d88930df558b. Report an issue: GitHub.