nexu-io/open-design · error · Error
openai response had neither b64_json nor url
Error message
openai response had neither b64_json nor url
What it means
Thrown by renderOpenAIImage when data[0] exists but contains neither b64_json nor url. The OpenAI image contract requires exactly one of these fields per entry; their absence indicates a malformed or partial upstream response (e.g. a moderation refusal that returned an empty entry, or an API version that uses a different field name).
Source
Thrown at apps/daemon/src/media/index.ts:972
}
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',
);
}
const baseUrl = (credentials.baseUrl || IMAGEROUTER_DEFAULT_BASE_URL).trim();
const wireModel = (credentials.model || ctx.wireModel).trim();View on GitHub (pinned to 5be4028344)
Solutions
- Inspect data[0] to see which fields it does carry, and adjust the renderer or the deployment to emit b64_json or url.
- Rephrase the prompt to avoid moderation-triggering content.
- Switch to a GA model id with a stable response schema.
- For Azure, set the deployment output format to PNG/JPEG so b64_json is populated.
Example fix
// before: preview deployment returns {data:[{revised_prompt:'...'}]}
// after: use GA deployment that returns {data:[{b64_json:'...'}]}
od media generate --surface image --model gpt-image-1 --prompt "..." Defensive patterns
Strategy: try-catch
Validate before calling
function isOpenAIImageEntry(entry: unknown): entry is { b64_json?: string; url?: string } {
return Boolean(entry && typeof entry === 'object' && ((entry as any).b64_json || (entry as any).url));
} Type guard
function isOpenAIImageEntry(entry: unknown): entry is { b64_json?: string; url?: string } {
return Boolean(entry && typeof entry === 'object' && ((entry as any).b64_json || (entry as any).url));
} Try / catch
try {
return await renderOpenAIImage(ctx, credentials);
} catch (err) {
const m = err instanceof Error ? err.message : '';
if (m === 'openai response had neither b64_json nor url') {
// usually moderation or schema skew; do not retry the same prompt
throw new UserActionableError('OpenAI returned an empty image entry (possibly moderation). Rephrase the prompt.');
}
throw err;
} Prevention
- Avoid prompts likely to trip content filters; this error often masks a moderation refusal.
- Use GA model ids whose response schema is stable.
- For Azure, set the deployment output format to a known image type so b64_json is populated.
When it happens
Trigger: Content moderation triggered and the entry was returned empty; using a beta/preview API version that returns a different field (e.g. 'image' instead of 'b64_json'); upstream returned a stub entry on partial failure; Azure deployment configured with output-format the daemon does not recognize.
Common situations: Prompt tripped safety filters; preview model on Azure with a non-standard response format; misconfigured deployment returning metadata-only entries.
Related errors
- openai non-JSON response: ${truncate(text, 200)}
- openai response had no data[0]
- ${providerTag} response had neither b64_json nor url
- ${tag} ${resp.status}: ${truncate(text, 240)}
- openai image fetch ${imgResp.status}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/1bd126cc096620a4.
Report an issue: GitHub.