musistudio/claude-code-router · error · Error

${resolved.model} is not a ${expectedKind} generation model.

Error message

${resolved.model} is not a ${expectedKind} generation model.

What it means

After resolving the provider, the service checks that a known model kind (image vs video) matches the operation: an image model cannot serve video-generate and vice versa. Only applies when the model's kind is recognizable.

Source

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

  return undefined;
}

export function resolveProviderMediaTarget(config: AppConfig, selector: string, operation?: MediaOperation): GatewayMediaTarget {
  const normalizedSelector = normalizeMediaModelSelector(config, selector, operation);
  const registry = modelRegistryForConfig(config);
  let resolved = registry.resolveProviderModel(normalizedSelector);
  if (!resolved) {
    const parsed = parseProviderModelSelector(normalizedSelector);
    const provider = parsed ? registry.findProvider(parsed.provider) : undefined;
    if (provider && isImportedGrokAgentProvider(provider) && grokMediaModelKind(parsed?.model)) {
      resolved = { model: parsed!.model, provider };
    }
  }
  if (!resolved) throw new Error(`Media model is not configured by a provider: ${normalizedSelector}`);
  const expectedKind = operation === "video-generate" ? "video" : operation ? "image" : undefined;
  const modelKind = grokMediaModelKind(resolved.model);
  if (expectedKind && modelKind && modelKind !== expectedKind) {
    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.`);

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Use a video model for video-generate and an image model for image operations
  2. Set operation-specific model/fallback chains
  3. Fix the model id to the correct family variant

Example fix

// before
{ operation: "video-generate", model: "openai/gpt-image-1" }
// after
{ operation: "video-generate", model: "openai/sora-video" }
Defensive patterns

Strategy: validation

Validate before calling

const kind = operation === "video-generate" ? "video" : "image";
if (grokMediaModelKind(model) && grokMediaModelKind(model) !== kind) throw new Error("wrong kind");

Type guard

const modelMatchesOperation = (model: string, op?: MediaOperation): boolean => { const k = grokMediaModelKind(model); return !k || (op === "video-generate" ? k === "video" : k === "image"); };

Try / catch

try { await call(); } catch (e) { if (e instanceof Error && /is not a (image|video) generation model/.test(e.message)) return wrongModel(); throw e; }

Prevention

When it happens

Trigger: Using an image generation model for a video-generate operation, or a video model for an image operation.

Common situations: Switching operations but reusing the previous model selector; fallback lists shared between image and video operations.

Related errors


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