{"record":{"id":"7c1a73dc8789d638","repo":"nexu-io/open-design","slug":"custom-image-api-model-required-configure-the-pr","errorCode":null,"errorMessage":"Custom Image API model required — configure the provider model in Settings","messagePattern":"Custom Image API model required — configure the provider model in Settings","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/index.ts","lineNumber":1065,"sourceCode":"    bytes,\n    providerNote: `imagerouter/${wireModel} · ${imageRouterSizeFor(ctx.aspect, 'video')} · ${seconds === 'auto' ? 'auto' : `${seconds}s`} · ${bytes.length} bytes`,\n    suggestedExt: '.mp4',\n  };\n}\n\nasync function renderCustomOpenAIImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {\n  const baseUrl = (credentials.baseUrl || '').trim();\n  if (!baseUrl) {\n    throw new Error(\n      'Custom Image API base URL required — configure an OpenAI-compatible /v1/images/generations or /v1/images/edits endpoint in Settings',\n    );\n  }\n  const wireModel = (\n    credentials.model\n    || (ctx.wireModel !== CUSTOM_IMAGE_MODEL_ID ? ctx.wireModel : '')\n  ).trim();\n  if (!wireModel) {\n    throw new Error(\n      'Custom Image API model required — configure the provider model in Settings',\n    );\n  }\n\n  const headers: Record<string, string> = {\n    'content-type': 'application/json',\n  };\n  if (credentials.apiKey) {\n    headers.authorization = `Bearer ${credentials.apiKey}`;\n  }\n  const body: Record<string, unknown> = {\n    prompt: ctx.prompt || 'A high-quality reference image.',\n    model: wireModel,\n    n: 1,\n    size: openaiSizeFor('gpt-image-1', ctx.aspect),\n  };\n  let url = buildOpenAIImageUrl(baseUrl, false);\n  if (ctx.imageRef?.dataUrl) {","sourceCodeStart":1047,"sourceCodeEnd":1083,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/index.ts#L1047-L1083","documentation":"Thrown by renderCustomOpenAIImage after baseUrl is set but no wireModel can be resolved. wireModel falls back from credentials.model to ctx.wireModel only when ctx.wireModel is not the sentinel CUSTOM_IMAGE_MODEL_ID ('custom-image'); if both are missing/empty the renderer refuses because body.model would be blank. The custom provider never has a default model name, so the user must supply one.","triggerScenarios":"Custom Image API configured with a baseUrl but model left blank in Settings; alias resolves ctx.wireModel to the 'custom-image' sentinel so it is intentionally discarded.","commonSituations":"User filled in URL but not the model field; settings form split across tabs and the model field was missed; an alias pointed the catalog id at itself.","solutions":["In Settings -> Media Providers -> Custom Image API, populate the model field with the wire name your gateway expects (e.g. 'flux-pro', 'sd3.5-large').","Pass --model <wire-name> on the CLI if invoking directly so ctx.wireModel is a real name rather than the sentinel.","Save the settings and re-run; the next failure (if any) will be an upstream HTTP error, which means URL+model+key are wired correctly."],"exampleFix":"// before: --model custom-image, no model in Settings\n// after: set --model to the wire name\nod media generate --surface image --model custom-image --prompt \"...\" \\\n  # plus configure model=flux-pro in Settings -> Media Providers -> Custom Image API","handlingStrategy":"validation","validationCode":"const CUSTOM_IMAGE_MODEL_ID = 'custom-image';\nfunction resolveCustomWireModel(creds: {model?: string}, ctxWireModel: string): string {\n  const m = (creds.model || (ctxWireModel !== CUSTOM_IMAGE_MODEL_ID ? ctxWireModel : '')).trim();\n  if (!m) throw new Error('Custom Image API model required — configure the provider model in Settings');\n  return m;\n}","typeGuard":"function hasCustomWireModel(creds: {model?:string}, ctxWireModel: string): boolean {\n  const m = (creds.model || (ctxWireModel !== 'custom-image' ? ctxWireModel : '')).trim();\n  return m.length > 0;\n}","tryCatchPattern":null,"preventionTips":["When configuring the custom-image provider in Settings, fill in both baseUrl and model.","Avoid using 'custom-image' as an alias target — the renderer treats it as the sentinel and discards it.","Pass the real wire name via --model on the CLI for one-off runs."],"tags":["media","provider-config","custom-image","configuration","model-resolution"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}