{"record":{"id":"675ee986908b131e","repo":"musistudio/claude-code-router","slug":"no-compatible-media-api-model-is-available-select","errorCode":null,"errorMessage":"No compatible media API model is available. Select a provider model that declares image or video generation support.","messagePattern":"No compatible media API model is available\\. Select a provider model that declares image or video generation support\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/media/service.ts","lineNumber":773,"sourceCode":"  const credential = sortProviderCredentialsForConfig(activeProviderCredentials(provider))[0];\n  return {\n    model: resolved.model,\n    protocol,\n    providerBaseUrl: providerBaseUrl.trim(),\n    providerName: provider.name,\n    providerSelector: credential\n      ? providerCredentialInternalName(provider, selectorProtocol, credential)\n      : capability || isImportedGrokAgentProvider(provider)\n        ? providerCapabilityInternalName(provider, protocol)\n        : providerRuntimeId(provider)\n  };\n}\n\nfunction normalizeMediaModelSelector(config: AppConfig, selector: string, operation?: MediaOperation): string {\n  const kind = operation === \"video-generate\" ? \"video\" : \"image\";\n  const migrated = migrateLegacyGrokMediaModelSelector(config.Providers, requiredModelSelector(selector), kind);\n  if (!migrated) {\n    throw new Error(\"No compatible media API model is available. Select a provider model that declares image or video generation support.\");\n  }\n  return migrated;\n}\n\nfunction normalizeGatewayTransport(transport: GatewayMediaTransport): GatewayMediaTransport {\n  return {\n    ...transport,\n    baseUrl: transport.baseUrl.replace(/\\/+$/g, \"\")\n  };\n}\n\nexport const mediaService = new MediaService();\n\nexport const mediaServiceForTest = {\n  isSafeImplicitWorkingDirectory\n};\n","sourceCodeStart":755,"sourceCodeEnd":790,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/core/src/media/service.ts#L755-L790","documentation":"normalizeMediaModelSelector migrates the selector to a currently available media model of the requested kind; if migration returns nothing (no compatible image/video model exists for the selector's provider), this catch-all is thrown. It typically fires for legacy Grok media selectors whose models no longer exist.","triggerScenarios":"Passing a legacy or removed Grok media model selector for which no migration target of the requested kind is configured.","commonSituations":"Version upgrades that renamed/removed bundled Grok media models; configs still referencing old selector strings.","solutions":["Update the selector to a currently supported image/video model id","Ensure the provider hosting the replacement model is configured","Remove stale model references from defaults and fallback lists"],"exampleFix":"// before\nmodel: \"grok-2-image-old\"\n// after\nmodel: \"xai/grok-2-image\"","handlingStrategy":"try-catch","validationCode":"const migrated = migrateLegacyGrokMediaModelSelector(config.Providers, selector, kind);\nif (!migrated) selector = currentDefaultMediaModel(kind);","typeGuard":"null","tryCatchPattern":"try { await call(); } catch (e) { if (e instanceof Error && e.message.includes(\"No compatible media API model\")) return updateModelSelector(); throw e; }","preventionTips":["Upgrade legacy selector strings after version bumps","Add startup checks for removed model ids"],"tags":["media","model-migration","legacy"],"backgroundTag":"legacy-model-selector","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}