{"record":{"id":"4d4ba8691d1449e7","repo":"CherryHQ/cherry-studio","slug":"modelscope-provider-requires-a-non-empty-baseurl","errorCode":null,"errorMessage":"ModelScope provider requires a non-empty `baseURL`.","messagePattern":"ModelScope provider requires a non-empty `baseURL`\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/provider/custom/modelscope/modelscopeProvider.ts","lineNumber":51,"sourceCode":" * registry (`resolveImageTransport`) so the job handler can rebuild the same\n * transport after a restart from the re-resolved provider settings.\n */\nexport function buildModelscopeTransport(settings: ModelscopeProviderSettings): ImageGenerationTransport {\n  return createModelscopeTransport({\n    apiKey: settings.apiKey ?? '',\n    baseURL: settings.imageBaseURL || DEFAULT_MODELSCOPE_BASE_URL\n  })\n}\n\n/**\n * Unified ModelScope (魔搭) provider: OpenAI-compatible chat/embedding off\n * `settings.baseURL`, plus an async submit/poll image transport off\n * `settings.imageBaseURL` (defaults to `https://api-inference.modelscope.cn`).\n */\nexport function createModelscopeProvider(settings: ModelscopeProviderSettings = {}): ModelscopeProvider {\n  const { baseURL, fetch: customFetch } = settings\n  if (!baseURL) {\n    throw new Error('ModelScope provider requires a non-empty `baseURL`.')\n  }\n\n  const resolveApiKey = () =>\n    loadApiKey({ apiKey: settings.apiKey, environmentVariableName: 'MODELSCOPE_API_KEY', description: 'ModelScope' })\n\n  const authHeaders = () => ({\n    Authorization: `Bearer ${resolveApiKey()}`,\n    ...settings.headers\n  })\n\n  const url = ({ path }: { path: string; modelId: string }) => `${withoutTrailingSlash(baseURL)}${path}`\n\n  const createChatModel = (modelId: string) =>\n    new OpenAICompatibleChatLanguageModel(modelId, {\n      provider: `${MODELSCOPE_PROVIDER_NAME}.chat`,\n      url,\n      headers: authHeaders,\n      fetch: customFetch","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/provider/custom/modelscope/modelscopeProvider.ts#L33-L69","documentation":"Thrown by `createModelscopeProvider` when `settings.baseURL` is falsy. Unlike DashScope/DMXAPI, the image transport's `imageBaseURL` has a built-in default (`DEFAULT_MODELSCOPE_BASE_URL`), so this guard specifically protects the chat/embedding OpenAI-compatible endpoint which has no default. Chat and embedding calls need an explicit host.","triggerScenarios":"Instantiating the ModelScope provider with no `baseURL` — `createModelscopeProvider({})`. The image transport alone would still work (defaults apply), but chat/embedding would have no target.","commonSituations":"ModelScope provider added in settings with only an image endpoint configured; the API host field left blank; a migration dropped `baseURL`.","solutions":["Set `baseURL` on the ModelScope provider settings to the OpenAI-compatible host, e.g. `https://api-inference.modelscope.cn/v1/`.","Verify the provider config builder forwards the user-configured host.","If only using image generation, prefer `buildModelscopeTransport` directly (it has a default base)."],"exampleFix":"// before\ncreateModelscopeProvider({ apiKey: 'ms-...' })\n// after\ncreateModelscopeProvider({ apiKey: 'ms-...', baseURL: 'https://api-inference.modelscope.cn/v1/' })","handlingStrategy":"validation","validationCode":"function assertModelscopeSettings(s: { baseURL?: string }) {\n  if (!s.baseURL) throw new Error('ModelScope baseURL required before creating provider')\n}\nassertModelscopeSettings(settings)\nconst provider = createModelscopeProvider(settings)","typeGuard":"const hasModelscopeBaseURL = (s: { baseURL?: string }): s is { baseURL: string } =>\n  typeof s.baseURL === 'string' && s.baseURL.trim().length > 0","tryCatchPattern":null,"preventionTips":["Make baseURL required in the ModelScope settings schema","For image-only use, prefer buildModelscopeTransport (has a default base)","Validate provider config before factory creation"],"tags":["config","validation","modelscope","base-url"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}