musistudio/claude-code-router · error · Error

Video fallback model ${selector} uses ${target.protocol}, bu

Error message

Video fallback model ${selector} uses ${target.protocol}, but primary model ${modelSelector} uses ${primaryTarget.protocol}. Configure video fallback models with the same media protocol.

What it means

When planning a video-generate request, MediaService verifies that every fallback model speaks the same media protocol (e.g. xai_video_generations vs openai_video_generations) as the primary model, because mid-request failover cannot switch protocols. A mismatch aborts planning unless explicitly permitted.

Source

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

  private mediaModelPlan(operation: MediaOperation, modelInput: MediaModelInput, options: { dropIncompatibleVideoFallbacks?: boolean } = {}): MediaModelPlan {
    const config = this.requireConfig();
    const source = typeof modelInput === "string" ? { modelSelector: modelInput } : modelInput;
    const modelSelector = normalizeMediaModelSelector(config, source.modelSelector, operation);
    const primaryTarget = resolveProviderMediaTarget(config, modelSelector, operation);
    const fallbackModelSelectors: string[] = [];
    const retryCount = clampInteger(source.retryCount ?? 0, 0, ROUTER_FALLBACK_MAX_RETRY_COUNT);
    for (const sourceSelector of source.fallbackModelSelectors ?? []) {
      const selector = normalizeMediaModelSelector(config, sourceSelector, operation);
      if (selector === modelSelector || fallbackModelSelectors.includes(selector)) {
        continue;
      }
      const target = resolveProviderMediaTarget(config, selector, operation);
      if (operation === "video-generate" && target.protocol !== primaryTarget.protocol) {
        if (options.dropIncompatibleVideoFallbacks) {
          continue;
        }
        throw new Error(
          `Video fallback model ${selector} uses ${target.protocol}, but primary model ${modelSelector} uses ${primaryTarget.protocol}. ` +
          "Configure video fallback models with the same media protocol."
        );
      }
      fallbackModelSelectors.push(selector);
    }
    return {
      fallbackModelSelectors,
      modelSelector,
      retryCount
    };
  }

  private videoToolBindingForRuntime(binding: MediaToolBinding): MediaToolBinding {
    const config = this.requireConfig();
    const modelSelector = normalizeMediaModelSelector(config, binding.modelSelector, "video-generate");
    const primaryTarget = resolveProviderMediaTarget(config, modelSelector, "video-generate");
    const fallbackModelSelectors: string[] = [];

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Set the video fallback models to providers using the same media protocol as the primary
  2. Remove the incompatible model from the video fallback list
  3. Pass dropIncompatibleVideoFallbacks: true in plan options to silently skip mismatched fallbacks

Example fix

// before
{ model: "grok-video-primary", fallbacks: ["openai/sora"] }
// after
{ model: "grok-video-primary", fallbacks: ["xai/grok-video-2"] }
Defensive patterns

Strategy: validation

Validate before calling

const plan = service.mediaModelPlan(config, { operation: "video-generate", dropIncompatibleVideoFallbacks: true });

Type guard

null

Try / catch

try { service.mediaModelPlan(config, opts); } catch (e) { if (e instanceof Error && e.message.includes("same media protocol")) {/* align fallbacks */} throw e; }

Prevention

When it happens

Trigger: Calling mediaModelPlan (or modelPlan) for video-generate where the primary video model resolves to one protocol and a fallback model resolves to another provider protocol.

Common situations: Mixing an xAI/Grok video primary with an OpenAI-compatible video fallback (or vice versa) in the model fallback chain configuration.

Related errors


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