musistudio/claude-code-router · error · Error

Provider ${provider.name} does not configure a media API bas

Error message

Provider ${provider.name} does not configure a media API base URL.

What it means

Once protocol and capability are resolved, the provider needs a base URL for media API calls, sourced from the capability's baseUrl or provider baseurl/baseUrl/api_base_url fields. All-empty values throw before any HTTP request.

Source

Thrown at packages/core/src/media/service.ts:750

    throw new Error(`${resolved.model} is not a ${expectedKind} generation model.`);
  }
  const provider = resolved.provider;
  const kind = expectedKind ?? modelKind;
  if (!kind || !providerSupportsMediaKind(provider, kind)) {
    throw new Error(`Provider ${provider.name} does not declare ${kind ?? "media"} generation support.`);
  }
  const protocol: GatewayMediaProtocol = kind === "video"
    ? provider.capabilities?.some((item) => item.type === "xai_video_generations") || isImportedGrokAgentProvider(provider)
      ? "xai_video_generations"
      : "openai_video_generations"
    : "openai_image_generations";
  const capability = provider.capabilities?.find((item) => item.type === protocol) ??
    (protocol === "xai_video_generations" && isImportedGrokAgentProvider(provider)
      ? provider.capabilities?.find((item) => item.type === "openai_video_generations")
      : undefined);
  const providerBaseUrl = capability?.baseUrl ?? provider.baseurl ?? provider.baseUrl ?? provider.api_base_url;
  if (!providerBaseUrl?.trim()) {
    throw new Error(`Provider ${provider.name} does not configure a media API base URL.`);
  }
  const selectorProtocol = capability || isImportedGrokAgentProvider(provider)
    ? protocol
    : inferProtocol(provider);
  const credential = sortProviderCredentialsForConfig(activeProviderCredentials(provider))[0];
  return {
    model: resolved.model,
    protocol,
    providerBaseUrl: providerBaseUrl.trim(),
    providerName: provider.name,
    providerSelector: credential
      ? providerCredentialInternalName(provider, selectorProtocol, credential)
      : capability || isImportedGrokAgentProvider(provider)
        ? providerCapabilityInternalName(provider, protocol)
        : providerRuntimeId(provider)
  };
}

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Set baseUrl (or baseurl/api_base_url) on the provider config
  2. Set baseUrl on the specific media capability entry
  3. Verify env interpolation for the base URL resolves in the running environment

Example fix

// before
{ name: "my-openai", capabilities: [{ type: "openai_image_generations" }] }
// after
{ name: "my-openai", baseUrl: "https://api.example.com/v1", capabilities: [{ type: "openai_image_generations" }] }
Defensive patterns

Strategy: validation

Validate before calling

const p = registry.findProvider(parsed.provider);
const cap = p?.capabilities?.find(c => c.type === protocol);
const base = cap?.baseUrl ?? p?.baseurl ?? p?.baseUrl ?? p?.api_base_url;
if (!base?.trim()) throw new Error("missing media base URL");

Type guard

const hasMediaBaseUrl = (provider: Provider, protocol: string): boolean => Boolean((provider.capabilities?.find(c => c.type === protocol)?.baseUrl ?? provider.baseurl ?? provider.baseUrl ?? provider.api_base_url ?? "").trim());

Try / catch

try { await call(); } catch (e) { if (e instanceof Error && e.message.includes("media API base URL")) return configError(); throw e; }

Prevention

When it happens

Trigger: Provider entry has none of baseurl, baseUrl, api_base_url, and the matched capability has no baseUrl either.

Common situations: Env-var-based base URL not set in the runtime environment; provider YAML key misspelled; capability object copied without its baseUrl.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/0e411155dcf203c5. Report an issue: GitHub.