{"record":{"id":"27c074ae611c5db1","repo":"nexu-io/open-design","slug":"grok-image-fetch-imgresp-status","errorCode":null,"errorMessage":"grok image fetch ${imgResp.status}","messagePattern":"grok image fetch (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/index.ts","lineNumber":1653,"sourceCode":"  }));\n  const text = await resp.text();\n  if (!resp.ok) {\n    throw new Error(`grok image ${resp.status}: ${truncate(text, 240)}`);\n  }\n  let data: any;\n  try {\n    data = JSON.parse(text);\n  } catch {\n    throw new Error(`grok image non-JSON: ${truncate(text, 200)}`);\n  }\n  const entry = data && Array.isArray(data.data) ? data.data[0] : null;\n  if (!entry) throw new Error('grok image response had no data[0]');\n  let bytes;\n  if (entry.b64_json) {\n    bytes = Buffer.from(entry.b64_json, 'base64');\n  } else if (entry.url) {\n    const imgResp = await fetch(entry.url, withMediaRequestInit(ctx));\n    if (!imgResp.ok) throw new Error(`grok image fetch ${imgResp.status}`);\n    bytes = Buffer.from(await imgResp.arrayBuffer());\n  } else {\n    throw new Error('grok image response missing b64_json/url');\n  }\n  // xAI's Imagine returns JPEG by default (no format option in the API\n  // surface), but PNG/WebP are technically possible. Sniff the magic\n  // bytes so the on-disk extension matches reality — saving JPEG bytes\n  // as `.png` confuses Finder previews and any downstream consumer that\n  // trusts the extension.\n  return {\n    bytes,\n    providerNote: `grok/${ctx.wireModel} · ${aspectRatio} · ${bytes.length} bytes`,\n    suggestedExt: sniffImageExt(bytes),\n  };\n}\n\nasync function renderNanoBananaImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {\n  const apiKey = credentials.apiKey;","sourceCodeStart":1635,"sourceCodeEnd":1671,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/index.ts#L1635-L1671","documentation":"Thrown when xAI's image response uses the `url` delivery path (no b64_json) and the secondary fetch of that URL returns a non-2xx status. The request body asks for `response_format: 'b64_json'`, so reaching this branch means xAI ignored the format hint and returned a hosted URL that is now unreachable, expired, or access-gated.","triggerScenarios":"xAI returns `{data:[{url:'https://...'}]}` and the URL (a) expired before the daemon fetched it, (b) requires the same bearer auth used for generation but withMediaRequestInit did not attach it, (c) lives behind a CDN that 403/404s requests without a referer, or (d) the host returned 5xx during a transient outage.","commonSituations":"Slow networks where the URL TTL lapses before download, corporate proxies stripping auth headers, xAI regional CDN incidents, or pointing baseUrl at a gateway that issues short-lived signed URLs.","solutions":["Retry the render — short-lived URL expiry is the most common cause and a fresh generation returns a fresh URL.","Verify withMediaRequestInit propagates ctx auth/headers to the secondary fetch; if the URL is xAI-hosted it may need the bearer token.","Check xAI status page for image-CDN incidents if the status is 5xx.","If reproducible, force inline delivery by ensuring response_format:'b64_json' is honoured upstream, or pin credentials.baseUrl to the official endpoint."],"exampleFix":"// before\nconst imgResp = await fetch(entry.url, withMediaRequestInit(ctx));\nif (!imgResp.ok) throw new Error(`grok image fetch ${imgResp.status}`);\n\n// after — one retry on transient host errors, then a clearer message\nlet imgResp = await fetch(entry.url, withMediaRequestInit(ctx));\nif (!imgResp.ok && imgResp.status >= 500) {\n  await sleep(1000);\n  imgResp = await fetch(entry.url, withMediaRequestInit(ctx));\n}\nif (!imgResp.ok) {\n  throw new Error(`grok image fetch ${imgResp.status} for ${truncate(entry.url, 80)}`);\n}","handlingStrategy":"retry","validationCode":"// Validate the URL before fetching, and confirm it is still fresh\nfunction isValidGrokImageUrl(u: unknown): u is string {\n  return typeof u === 'string' && /^https?:\\/\\//.test(u) && u.length < 4096;\n}","typeGuard":"function isFreshSignedUrl(u: string, maxAgeMs = 5 * 60_000): boolean {\n  // xAI signed URLs sometimes embed an expiry; if present, ensure it is in the future\n  const m = u.match(/[?&](?:exp|expires|X-Expiry)=(\\d+)/);\n  if (!m) return true; // unknown expiry — assume fresh\n  return Number(m[1]) * 1000 > Date.now() + maxAgeMs;\n}","tryCatchPattern":"let bytes: Buffer | undefined;\nfor (let attempt = 0; attempt < 2; attempt++) {\n  try {\n    const r = await fetch(entry.url, withMediaRequestInit(ctx));\n    if (!r.ok) {\n      if (attempt === 0 && (r.status >= 500 || r.status === 429)) continue;\n      throw new Error(`grok image fetch ${r.status}`);\n    }\n    bytes = Buffer.from(await r.arrayBuffer());\n    break;\n  } catch (e) {\n    if (attempt === 1) throw e;\n  }\n}","preventionTips":["Prefer response_format:'b64_json' so no secondary fetch is needed; only fall back to URL when inline is unavailable.","Fetch the URL immediately after receiving it — signed URLs have short TTLs.","Carry ctx auth/headers into the secondary fetch in case the host requires them.","Retry once on 5xx/429 before surfacing the error to the user."],"tags":["grok","xai","image-generation","network","secondary-fetch","provider-api"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}