mastra-ai/mastra · error · Error

No API URL found for ${providerId}/${modelId}

Error message

No API URL found for ${providerId}/${modelId}

What it means

In resolveLanguageModel, the moonshotai and moonshotai-cn providers are routed through the Anthropic-compatible SDK, which requires an explicit baseURL (Moonshot's Anthropic-compatible endpoint). If buildUrl produced no baseURL (no provider URL template result and no <PROVIDER>_BASE_URL env override), this error is thrown instead of creating a misconfigured provider.

Source

Thrown at packages/core/src/llm/model/gateways/models-dev.ts:387

        ) as unknown as GatewayLanguageModel;
      case 'xai':
        return createXai({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId);
      case 'deepseek':
        return createDeepSeek({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      case 'perplexity':
        return createPerplexity({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      case 'cerebras':
        return createCerebras({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      case 'togetherai':
        return createTogetherAI({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      case 'deepinfra':
        return createDeepInfra({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      case 'vercel':
        return createGateway({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      case 'moonshotai':
      case 'moonshotai-cn': {
        // moonshotai uses Anthropic-compatible API endpoint
        if (!baseURL) throw new Error(`No API URL found for ${providerId}/${modelId}`);
        return createAnthropic({ apiKey, baseURL, headers: mastraHeaders })(modelId);
      }
      default: {
        // Check if this provider uses a specific SDK package (e.g., kimi-for-coding uses @ai-sdk/anthropic).
        // A per-model override wins over the provider default.
        const config = this.providerConfigs[providerId];
        const npm = override?.npm ?? config?.npm;

        // Pattern match for any alibaba variant (alibaba, alibaba-cn, alibaba-coding-plan, etc.)
        if (providerId.includes('alibaba')) {
          if (!baseURL) throw new Error(`No API URL found for ${providerId}/${modelId}`);
          return createAlibaba({ apiKey, baseURL, headers: mastraHeaders })(modelId);
        }

        if (npm === '@ai-sdk/anthropic') {
          if (!baseURL) throw new Error(`No API URL found for ${providerId}/${modelId}`);
          return createAnthropic({ apiKey, baseURL, headers: mastraHeaders })(modelId);
        }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set the provider base URL env var, e.g. process.env.MOONSHOTAI_BASE_URL='https://api.moonshot.ai/anthropic' (or the CN endpoint for moonshotai-cn), before model resolution.
  2. Check that any env var the provider's URL template interpolates is actually set (the template silently yields no URL when a placeholder is missing).
  3. If using a custom gateway/provider registration, supply a default baseURL in the provider config so buildUrl always resolves.
  4. Verify the model id/provider id spelling — an unrecognized provider may fall into the config-less path with no URL.

Example fix

// before
const agent = new Agent({ model: 'moonshotai/kimi-k2-0711-preview' });
// after
process.env.MOONSHOTAI_BASE_URL ??= 'https://api.moonshot.ai/anthropic';
const agent = new Agent({ model: 'moonshotai/kimi-k2-0711-preview' });
Defensive patterns

Strategy: validation

Validate before calling

for (const v of ['MOONSHOTAI_BASE_URL']) {
  if (!process.env[v]) throw new Error(`${v} must be set for moonshotai models`);
}

Type guard

function hasBaseUrl(providerId: string, env: NodeJS.ProcessEnv = process.env): boolean {
  const key = `${providerId.toUpperCase().replace(/-/g, '_')}_BASE_URL`;
  return typeof env[key] === 'string' && env[key]!.length > 0;
}

Try / catch

try {
  const model = await gateway.resolveLanguageModel({ modelId, providerId: 'moonshotai', apiKey });
} catch (e) {
  if (e instanceof Error && e.message.includes('No API URL found')) {
    console.error('Set MOONSHOTAI_BASE_URL before resolving moonshotai models');
  }
  throw e;
}

Prevention

When it happens

Trigger: Resolving a model like 'moonshotai/kimi-k2...' or 'moonshotai-cn/...' via the models-dev gateway when neither the provider's URL template resolves (e.g. its env-interpolated template has a missing env var) nor MOONSHOTAI_BASE_URL / MOONSHOTAI_CN_BASE_URL is set.

Common situations: Relying on a models.dev URL template that depends on an env var you haven't set; pinning a custom MOONSHOTAI_BASE_URL that is empty string; a registry/config update where the provider lost its default URL; self-hosted or proxied Moonshot setups where the default template doesn't apply.

Related errors


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