nexu-io/open-design · error · Error
openai image fetch ${imgResp.status}
Error message
openai image fetch ${imgResp.status} What it means
Thrown by renderOpenAIImage when the response carried entry.url instead of b64_json and the secondary fetch of that URL returned a non-2xx status. OpenAI/Azure sometimes return a hosted image URL instead of inline bytes; the daemon downloads it before writing to disk, and a failure here means that download step broke, not the generation itself.
Source
Thrown at apps/daemon/src/media/index.ts:968
const text = await resp.text();
if (!resp.ok) {
const tag = azure ? 'azure-openai' : 'openai';
throw new Error(`${tag} ${resp.status}: ${truncate(text, 240)}`);
}
let data: any;
try {
data = JSON.parse(text);
} catch {
throw new Error(`openai non-JSON response: ${truncate(text, 200)}`);
}
const entry = data && Array.isArray(data.data) ? data.data[0] : null;
if (!entry) throw new Error('openai response had no data[0]');
let bytes;
if (entry.b64_json) {
bytes = Buffer.from(entry.b64_json, 'base64');
} else if (entry.url) {
const imgResp = await fetch(entry.url, withMediaRequestInit(ctx));
if (!imgResp.ok) throw new Error(`openai image fetch ${imgResp.status}`);
const arr = await imgResp.arrayBuffer();
bytes = Buffer.from(arr);
} else {
throw new Error('openai response had neither b64_json nor url');
}
const tag = azure ? 'azure-openai' : 'openai';
return {
bytes,
providerNote: `${tag}/${ctx.wireModel} · ${ctx.aspect} · ${bytes.length} bytes`,
suggestedExt: '.png',
};
}
async function renderImageRouterImage(ctx: MediaContext, credentials: ProviderConfig): Promise<RenderResult> {
if (!credentials.apiKey) {
throw new Error(
'no ImageRouter API key — configure it in Settings or set OD_IMAGEROUTER_API_KEY',View on GitHub (pinned to 5be4028344)
Solutions
- Retry the request — signed URL fetches are often transient.
- Request b64_json output instead of url if the integration supports it (forces inline bytes, no second fetch).
- Allowlist the OpenAI image CDN host (e.g. *.blob.core.windows.net for Azure, files.oaiusercontent.com for OpenAI) in egress rules.
- Check for clock skew on the daemon host — signed URLs validate against the upstream server clock.
Example fix
// before: response_format defaults to url and CDN is blocked // after: pin response_format to b64_json in your custom integration path body.response_format = 'b64_json';
Defensive patterns
Strategy: retry
Try / catch
try {
return await renderOpenAIImage(ctx, credentials);
} catch (err) {
const m = err instanceof Error ? err.message : '';
if (m.startsWith('openai image fetch ')) {
// signed-URL download failed; retry once, then suggest b64_json
await sleep(backoffMs);
return await renderOpenAIImage(ctx, credentials);
}
throw err;
} Prevention
- Prefer response_format=b64_json where the integration supports it to skip the secondary fetch.
- Allowlist the OpenAI blob CDN hosts (*.blob.core.windows.net, files.oaiusercontent.com) in egress rules.
- Keep daemon host clock synced (NTP) to avoid signed-URL skew.
When it happens
Trigger: OpenAI returns a signed url that expired before the follow-up fetch; the hosted-image CDN returns 403/404; a network egress filter blocks the image CDN host while allowing api.openai.com; corporate proxy allows the API but blocks the blob storage host.
Common situations: Long latency between generation and download causing URL expiry; restrictive egress firewall; transient CDN 5xx; signed-URL region mismatch.
Related errors
- ${providerTag} media fetch ${mediaResp.status}
- ${tag} ${resp.status}: ${truncate(text, 240)}
- openai non-JSON response: ${truncate(text, 200)}
- openai response had no data[0]
- openai response had neither b64_json nor url
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/d6b0462813364cc2.
Report an issue: GitHub.