nexu-io/open-design · error · Error

volcengine image response missing b64_json/url

Error message

volcengine image response missing b64_json/url

What it means

Thrown when the `data[0]` entry has neither `b64_json` nor `url`. The renderer supports both delivery modes; an entry with neither is an unexpected/unsupported response shape (new field, API change, or partial body).

Source

Thrown at apps/daemon/src/media/index.ts:1585

    throw new Error(`volcengine image ${resp.status}: ${truncate(text, 240)}`);
  }
  let data: any;
  try {
    data = JSON.parse(text);
  } catch {
    throw new Error(`volcengine image non-JSON: ${truncate(text, 200)}`);
  }
  const entry = data && Array.isArray(data.data) ? data.data[0] : null;
  if (!entry) throw new Error('volcengine 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(`volcengine image fetch ${imgResp.status}`);
    bytes = Buffer.from(await imgResp.arrayBuffer());
  } else {
    throw new Error('volcengine image response missing b64_json/url');
  }
  return {
    bytes,
    providerNote: `volcengine/${ctx.wireModel} · ${ctx.aspect} · ${bytes.length} bytes`,
    suggestedExt: '.png',
  };
}

// ---------------------------------------------------------------------------
// Provider: xAI Grok Imagine.
//
// Docs: https://docs.x.ai/developers/model-capabilities/{images,video}/generation
//   * Image: POST /v1/images/generations — synchronous, returns
//            {data:[{b64_json|url}]}; we ask for b64_json so the bytes
//            arrive in one round-trip.
//   * Video: POST /v1/videos/generations — may return the finished video
//            inline ({status:'done', video:{url}}) or an async stub
//            ({id, status:'pending'}); in the async case we poll

View on GitHub (pinned to 5be4028344)

Solutions

  1. Log the full `entry` object to see which fields Volcengine actually returned.
  2. Verify the API path is `/api/v3/images/generations` and the model is a Seedream image model.
  3. If a new delivery field appears, extend the `b64_json`/`url` branch in the renderer.

Example fix

// before
if (entry.b64_json) { bytes = Buffer.from(entry.b64_json, 'base64'); }
else if (entry.url) { /* fetch url */ }
else { throw new Error('volcengine image response missing b64_json/url'); }

// after (also accept a future revised_payload / base64 field)
const b64 = entry.b64_json || entry.b64 || entry.revised_payload;
if (b64) { bytes = Buffer.from(b64, 'base64'); }
else if (entry.url) { /* fetch url */ }
else { throw new Error(`volcengine image response missing b64_json/url; keys=${Object.keys(entry).join(',')}`); }
Defensive patterns

Strategy: type-guard

Type guard

type VolcengineImageEntry = { b64_json?: string; url?: string };
function hasImagePayload(e: unknown): e is VolcengineImageEntry {
  const o = e as any;
  return typeof o?.b64_json === 'string' || typeof o?.url === 'string';
}
if (!hasImagePayload(entry)) {
  throw new Error(`volcengine image response missing b64_json/url; keys=${Object.keys(entry).join(',')}`);
}

Prevention

When it happens

Trigger: Parsed `entry` where both `entry.b64_json` and `entry.url` are falsy. Happens on an API shape change (Volcengine adds a new delivery field), a partial/error entry returned with 2xx, or a `baseUrl` override returning a different schema.

Common situations: (1) Volcengine shipped an API change introducing a new field name; (2) error entry returned inside `data` with 2xx; (3) wrong API path returning a non-Seedream envelope.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/9712f485e826646d. Report an issue: GitHub.