nexu-io/open-design · error · Error
grok image non-JSON: ${truncate(text, 200)}
Error message
grok image non-JSON: ${truncate(text, 200)} What it means
Thrown when `JSON.parse(text)` fails on the Grok image response. xAI (or an intermediary) returned a 2xx body that isn't JSON — typically an HTML gateway/maintenance page — so up to 200 chars are surfaced for diagnosis instead of an opaque parse error.
Source
Thrown at apps/daemon/src/media/index.ts:1644
response_format: 'b64_json',
};
const resp = await fetch(`${baseUrl}/images/generations`, withMediaRequestInit(ctx, {
method: 'POST',
headers: {
'authorization': `Bearer ${credentials.apiKey}`,
'content-type': 'application/json',
},
body: JSON.stringify(body),
}));
const text = await resp.text();
if (!resp.ok) {
throw new Error(`grok image ${resp.status}: ${truncate(text, 240)}`);
}
let data: any;
try {
data = JSON.parse(text);
} catch {
throw new Error(`grok image non-JSON: ${truncate(text, 200)}`);
}
const entry = data && Array.isArray(data.data) ? data.data[0] : null;
if (!entry) throw new Error('grok image 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(`grok image fetch ${imgResp.status}`);
bytes = Buffer.from(await imgResp.arrayBuffer());
} else {
throw new Error('grok image response missing b64_json/url');
}
// xAI's Imagine returns JPEG by default (no format option in the API
// surface), but PNG/WebP are technically possible. Sniff the magic
// bytes so the on-disk extension matches reality — saving JPEG bytes
// as `.png` confuses Finder previews and any downstream consumer that
// trusts the extension.View on GitHub (pinned to 5be4028344)
Solutions
- Inspect the truncated body — HTML indicates a gateway/proxy; fix routing or wait out the outage.
- Verify `credentials.baseUrl` (or unset it to use the default `https://api.x.ai/v1`).
- Ensure the xAI host is reachable and not redirected on the daemon's network.
Defensive patterns
Strategy: try-catch
Validate before calling
function looksLikeXaiJson(text: string): boolean {
const head = text.slice(0, 100).trim();
return head.startsWith('{') || head.startsWith('[');
} Try / catch
try { data = JSON.parse(text); }
catch { throw new Error(`grok image non-JSON: ${truncate(text, 200)}`); } Prevention
- Confirm the daemon host reaches `api.x.ai` without an HTML redirect.
- Avoid overriding `baseUrl` unless you control the target.
- Log the response `Content-Type` to catch gateway HTML early.
When it happens
Trigger: 2xx Grok image response that fails `JSON.parse`. Gateway maintenance page, proxy HTML interstitial, captive-portal auth wall, or a `baseUrl` override pointing at a host that serves HTML.
Common situations: (1) xAI regional outage surfacing an HTML status page with a 2xx status; (2) corporate proxy injecting an HTML interstitial; (3) `baseUrl` mistyped to a path that serves HTML.
Related errors
- grok image fetch ${imgResp.status}
- volcengine non-JSON: ${truncate(taskText, 200)}
- volcengine image non-JSON: ${truncate(text, 200)}
- no xAI credentials — sign in with your SuperGrok subscriptio
- grok image ${resp.status}: ${truncate(text, 240)}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/6e666d3fbc41b7a1.
Report an issue: GitHub.