{"record":{"id":"4c923a254e1b5a0e","repo":"nexu-io/open-design","slug":"providertag-resp-status-truncate-text-24","errorCode":null,"errorMessage":"${providerTag} ${resp.status}: ${truncate(text, 240)}","messagePattern":"\\$\\{providerTag\\} \\$\\{resp\\.status\\}: \\$\\{truncate\\(text, 240\\)\\}","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/index.ts","lineNumber":1128,"sourceCode":"    providerNote: `custom-image/${wireModel} · ${body.size} · ${bytes.length} bytes`,\n    suggestedExt: sniffImageExt(bytes),\n  };\n}\n\nfunction customImageOverridesOpenAIModel(\n  ctx: MediaContext,\n  credentials: ProviderConfig | null,\n): credentials is ProviderConfig {\n  const baseUrl = credentials?.baseUrl?.trim();\n  const model = credentials?.model?.trim();\n  if (!baseUrl || !model) return false;\n  return model === ctx.model || model === ctx.wireModel;\n}\n\nasync function parseOpenAICompatibleJson(resp: Response, providerTag: string): Promise<any> {\n  const text = await resp.text();\n  if (!resp.ok) {\n    throw new Error(`${providerTag} ${resp.status}: ${truncate(text, 240)}`);\n  }\n  try {\n    return JSON.parse(text);\n  } catch {\n    throw new Error(`${providerTag} non-JSON response: ${truncate(text, 200)}`);\n  }\n}\n\nasync function bytesFromOpenAICompatibleData(data: any, providerTag: string, requestInit: MediaRequestInit = {}): Promise<Buffer> {\n  const entry = data && Array.isArray(data.data) ? data.data[0] : null;\n  if (!entry) throw new Error(`${providerTag} response had no data[0]`);\n  if (typeof entry.b64_json === 'string' && entry.b64_json) {\n    const raw = entry.b64_json.includes(',')\n      ? entry.b64_json.slice(entry.b64_json.indexOf(',') + 1)\n      : entry.b64_json;\n    return Buffer.from(raw, 'base64');\n  }\n  if (typeof entry.url === 'string' && entry.url) {","sourceCodeStart":1110,"sourceCodeEnd":1146,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/index.ts#L1110-L1146","documentation":"Generic non-2xx error from parseOpenAICompatibleJson, the shared helper used by the ImageRouter (and other OpenAI-compatible) renderers. providerTag identifies which integration ('imagerouter image', 'imagerouter video', etc.), resp.status is the upstream HTTP code, and the first 240 chars of the body are inlined. This centralizes the upstream-failure reporting for all OpenAI-compatible paths.","triggerScenarios":"ImageRouter gateway returns 401 (bad key), 402/429 (quota/rate), 404 (unknown model on the gateway), or 5xx; same family of failures for any other renderer that funnels through parseOpenAICompatibleJson.","commonSituations":"Expired gateway key; model id not enabled on the gateway plan; transient gateway outage; wrong baseUrl pointing at a non-ImageRouter host.","solutions":["Read the inlined status and body: 401/403 -> fix the key; 404 -> verify the model id is valid for the gateway; 429 -> back off; 5xx -> retry then check status.","Confirm baseUrl still points at the gateway (IMAGEROUTER_DEFAULT_BASE_URL or your custom override).","Verify the model id is enabled on your gateway plan dashboard.","Switch to a direct provider model if the gateway is persistently unavailable."],"exampleFix":"// before: model not enabled on ImageRouter plan -> 404\nod media generate --surface image --model <wrong-id> --prompt \"...\"\n// after: use a model id listed in the ImageRouter dashboard\nod media generate --surface image --model <enabled-id> --prompt \"...\"","handlingStrategy":"retry","validationCode":"function classifyCompatibleStatus(status: number, providerTag: string): 'retry'|'config'|'fatal' {\n  if (status === 429 || status >= 500) return 'retry';\n  if (status === 401 || status === 403) return 'config';\n  if (status === 404) return 'config'; // unknown model on gateway\n  return 'fatal';\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await parseOpenAICompatibleJson(resp, providerTag);\n} catch (err) {\n  const m = err instanceof Error ? err.message : '';\n  const match = m.match(/^(.*?) (\\d{3}):/);\n  if (match) {\n    const [, tag, s] = match;\n    const status = Number(s);\n    if (status === 429 || status >= 500) throw new RetryableError(m);\n    if (status === 401 || status === 403) throw new ConfigError(`${tag}: rotate API key`);\n    if (status === 404) throw new ConfigError(`${tag}: model id not enabled on gateway`);\n  }\n  throw err;\n}","preventionTips":["Verify the model id is enabled on the gateway plan before invoking.","Keep the gateway key fresh and within quota to avoid 401/402/429.","Read the inlined body to distinguish auth/quota/model-not-found before retrying."],"tags":["network","media","openai-compatible","http-status","upstream","imagerouter"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}