{"record":{"id":"9fb5346ff89cbe52","repo":"CherryHQ/cherry-studio","slug":"dmxapi-provider-requires-a-non-empty-baseurl-to","errorCode":null,"errorMessage":"DMXAPI provider requires a non-empty `baseURL` to build the image transport.","messagePattern":"DMXAPI provider requires a non-empty `baseURL` to build the image transport\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/provider/custom/dmxapi/dmxapiProvider.ts","lineNumber":97,"sourceCode":" * `createImageModelV3` below — the image-generation job's transport registry\n * (`resolveImageTransport`) uses this to decide whether DMXAPI generation goes\n * through the job. Native families (gpt-image / dall-e / imagen / gemini-image)\n * and the `openai-flat` compat fallback keep the in-SDK path.\n */\nexport function dmxapiUsesCustomTransport(modelId: string): boolean {\n  return resolveNativeImageFamily(modelId) === 'openai-compat-image' && resolveDmxapiFamily(modelId) !== 'openai-flat'\n}\n\n/**\n * Build the DMXAPI submit/poll image transport from provider settings. Shared\n * by the provider factory and the image-generation job's transport registry so\n * the job handler can rebuild the same transport after a restart from the\n * re-resolved provider settings.\n */\nexport function buildDmxapiTransport(settings: DmxapiProviderSettings): ImageGenerationTransport {\n  const chatBaseURL = settings.endpointBaseURLs?.[ENDPOINT_TYPE.OPENAI_CHAT_COMPLETIONS] ?? settings.baseURL\n  if (!chatBaseURL) {\n    throw new Error('DMXAPI provider requires a non-empty `baseURL` to build the image transport.')\n  }\n  return createDmxapiTransport({\n    apiKey: settings.apiKey ?? '',\n    // The transport POSTs to host-root paths (`/v1/images/...`), so strip the\n    // OpenAI-compat version suffix from the chat baseURL to avoid a double `/v1`.\n    baseURL: withoutTrailingApiVersion(chatBaseURL)\n  })\n}\n\nexport function createDmxapiProvider(settings: DmxapiProviderSettings = {}): DmxapiProvider {\n  const { baseURL, fetch: customFetch } = settings\n  if (!baseURL) {\n    throw new Error(\n      'DMXAPI 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 = () =>","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/provider/custom/dmxapi/dmxapiProvider.ts#L79-L115","documentation":"Thrown by `buildDmxapiTransport` when neither `settings.endpointBaseURLs[OPENAI_CHAT_COMPLETIONS]` nor `settings.baseURL` is set. The image transport POSTs to host-root paths (`/v1/images/...`) and needs a host to anchor them. This builder is shared by the provider factory and the image-generation job's transport registry, so it can also fire on a restart resume.","triggerScenarios":"Building the DMXAPI image transport from settings that carry no chat base URL — either the provider was created with neither field, or the job's restart-resume path re-resolved settings that lost the base URL.","commonSituations":"Provider record persisted without a base URL after a config edit; the job handler rebuilt the transport from a stale/partial settings snapshot; `endpointBaseURLs` was set for other endpoint types but not chat.","solutions":["Ensure `baseURL` (or `endpointBaseURLs[OPENAI_CHAT_COMPLETIONS]`) is set on the DMXAPI provider settings.","If hitting this on restart resume, verify the job re-resolves the full provider settings including the base URL.","Guard the settings object before calling `buildDmxapiTransport`."],"exampleFix":"// before\nbuildDmxapiTransport({ apiKey: 'sk-...' })\n// after\nbuildDmxapiTransport({ apiKey: 'sk-...', baseURL: 'https://www.dmxapi.cn/v1' })","handlingStrategy":"validation","validationCode":"const chatBaseURL = settings.endpointBaseURLs?.[ENDPOINT_TYPE.OPENAI_CHAT_COMPLETIONS] ?? settings.baseURL\nif (!chatBaseURL) {\n  throw new Error('Cannot build DMXAPI image transport — set baseURL or endpointBaseURLs[OPENAI_CHAT_COMPLETIONS]')\n}\nbuildDmxapiTransport(settings)","typeGuard":"const hasDmxapiChatBase = (s: DmxapiProviderSettings): boolean =>\n  !!(s.endpointBaseURLs?.[ENDPOINT_TYPE.OPENAI_CHAT_COMPLETIONS] ?? s.baseURL)","tryCatchPattern":null,"preventionTips":["Persist baseURL alongside apiKey in the provider record","On restart-resume, re-resolve the full settings snapshot before rebuilding the transport","Validate settings before calling buildDmxapiTransport"],"tags":["config","validation","dmxapi","base-url","image-transport"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}