mastra-ai/mastra · error

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

Error message

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

What it means

For an object config with an `id` field that is not mastra-prefixed, the id must be exactly "provider/model" (two slash-separated parts). Any other segment count (e.g. 1 part or 3+ parts) makes provider/model extraction ambiguous, so the constructor throws.

Source

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

        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,
          headers: config.headers,
        };
      }
    }

    this.provider = normalizedConfig.providerId;
    this.modelId = normalizedConfig.modelId;

    if (normalizedConfig.providerId === MASTRA_GATEWAY_ID) {
      const apiKey = normalizedConfig.apiKey ?? process.env['MASTRA_GATEWAY_API_KEY'];
      if (!apiKey) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Make the id exactly "provider/model" (e.g. "openai/text-embedding-3-small").
  2. For model ids containing slashes, use object config { providerId, modelId } so no slash splitting occurs.
  3. Prefix with "mastra/" if you actually want gateway routing (which permits longer ids).

Example fix

// before
new EmbeddingRouter({ id: "cohere/embed-v3.0/multilingual" });
// after
new EmbeddingRouter({ providerId: "cohere", modelId: "embed-v3.0/multilingual" });
Defensive patterns

Strategy: validation

Validate before calling

function assertProviderModelId(id) {
  if (!id.startsWith('mastra/') && id.split('/').length !== 2) {
    throw new Error(`Expected "provider/model", got: ${id}`);
  }
}
assertProviderModelId(config.id);

Type guard

const isPlainProviderModelId = (id) => !id.startsWith('mastra/') && id.split('/').length === 2 && id.split('/').every(Boolean);

Try / catch

try {
  router = new EmbeddingRouter({ id });
} catch (e) {
  if (e instanceof Error && e.message.includes('Expected format: "provider/model"')) {
    console.error(`id must be "provider/model": ${id}`);
  } else throw e;
}

Prevention

When it happens

Trigger: new EmbeddingRouter({ id: "openai" }) (missing model) or { id: "openai/text-embedding-3-small/v2" } (extra segment) — anything where id.split('/').length !== 2 without a mastra prefix.

Common situations: Passing just a provider name; model ids that naturally contain slashes (Azure, Bedrock, HF paths) without a mastra prefix; accidental double slashes.

Related errors


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