{"record":{"id":"fb8f175dae1bea09","repo":"CherryHQ/cherry-studio","slug":"dashscope-provider-requires-a-non-empty-baseurl","errorCode":null,"errorMessage":"DashScope provider requires a non-empty `baseURL`. An empty value would resolve fetch paths against the renderer process origin (app://, file://) and surface as opaque \"Failed to fetch\" errors.","messagePattern":"DashScope provider requires a non-empty `baseURL`\\. An empty value would resolve fetch paths against the renderer process origin \\(app://, file://\\) and surface as opaque \"Failed to fetch\" errors\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/provider/custom/dashscope/dashscopeProvider.ts","lineNumber":70,"sourceCode":"export function buildDashScopeTransport(settings: DashScopeProviderSettings): ImageGenerationTransport {\n  return createDashScopeTransport({\n    apiKey: settings.apiKey ?? '',\n    imageBaseURL: settings.imageBaseURL || DEFAULT_DASHSCOPE_IMAGE_BASE_URL\n  })\n}\n\n/**\n * Unified DashScope (Bailian) provider — chat, embedding, and image off one\n * `ProviderV3`. Chat / embedding go through the OpenAI-compatible SDK aimed at\n * `baseURL` (DashScope exposes `/compatible-mode/v1/`); image goes through the\n * native DashScope `/api/v1/services/aigc/*` endpoints via\n * `createImageGenerationModel + createDashScopeTransport` aimed at\n * `imageBaseURL`.\n */\nexport function createDashScopeProvider(settings: DashScopeProviderSettings = {}): DashScopeProvider {\n  const { baseURL, fetch: customFetch } = settings\n  if (!baseURL) {\n    throw new Error(\n      'DashScope provider requires a non-empty `baseURL`. An empty value would resolve fetch paths against the renderer process origin (app://, file://) and surface as opaque \"Failed to fetch\" errors.'\n    )\n  }\n\n  const resolveApiKey = () =>\n    loadApiKey({ apiKey: settings.apiKey, environmentVariableName: 'DASHSCOPE_API_KEY', description: 'DashScope' })\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  // DashScope chat uses /compatible-mode/v1; rerank uses /compatible-api/v1 on the same user-configured host.\n  const rerankBaseURL = getDashScopeRerankBaseURL(baseURL)\n  const rerankUrl = ({ path }: { path: string; modelId: string }) =>\n    `${rerankBaseURL}${path === '/rerank' ? '/reranks' : path}`","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/provider/custom/dashscope/dashscopeProvider.ts#L52-L88","documentation":"Thrown by the DashScope provider factory `createDashScopeProvider` when `settings.baseURL` is falsy. The guard fires eagerly because, inside Electron's main process, an empty base makes relative fetch paths resolve against the renderer origin (`app://`, `file://`), which surfaces as opaque \"Failed to fetch\" errors that hide the real cause. Failing fast with a clear message is preferred over a cryptic network failure later.","triggerScenarios":"Instantiating the provider via `createDashScopeProvider({})` or `createDashScopeProvider({ baseURL: '' })` — i.e. the provider config builder resolved no API host. Chat and embedding endpoints both need this base; `imageBaseURL` alone is not enough.","commonSituations":"The DashScope provider was added in settings but the API host field was left blank; a settings migration dropped the `baseURL` field; the user only filled the image endpoint, forgetting chat/embedding share the chat base.","solutions":["Set `baseURL` in the DashScope provider settings to the OpenAI-compatible chat host, e.g. `https://dashscope.aliyuncs.com/compatible-mode/v1/`.","Verify the provider config builder forwards the user-configured host into `baseURL` (not only `imageBaseURL`).","If only image generation is intended, confirm `buildDashScopeTransport` is the right entry point — but note the unified factory still requires `baseURL` for chat/embedding model wiring."],"exampleFix":"// before\ncreateDashScopeProvider({ apiKey: 'sk-...' })\n// after\ncreateDashScopeProvider({ apiKey: 'sk-...', baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1/' })","handlingStrategy":"validation","validationCode":"function assertDashScopeSettings(s: { baseURL?: string }) {\n  if (!s.baseURL) throw new Error('DashScope baseURL required before creating provider')\n}\nassertDashScopeSettings(settings)\nconst provider = createDashScopeProvider(settings)","typeGuard":"const hasBaseURL = (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 provider settings schema (non-empty string)","Validate provider config before passing to the factory","Cover the factory with a unit test that asserts it throws on missing baseURL"],"tags":["config","validation","dashscope","base-url","electron"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}