nexu-io/open-design · error · SystemExit
image API response did not contain data[0].b64_json
Error message
image API response did not contain data[0].b64_json
What it means
Raised by decode_response when response["data"][0] exists but is not a dict, or its b64_json field is missing/not a string. The script hard-requires a base64 PNG payload at data[0].b64_json and cannot fall back to a URL or any other field.
Source
Thrown at skills/hatch-pet/scripts/generate_pet_images.py:158
data=payload,
headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
method="POST",
)
with urllib.request.urlopen(req, timeout=300) as resp:
output_json.write_bytes(resp.read())
response = json.loads(output_json.read_text(encoding="utf-8"))
if response.get("error"):
raise SystemExit(json.dumps(response["error"], indent=2))
return response
def decode_response(response: dict[str, object], output_image: Path) -> None:
data = response.get("data")
if not isinstance(data, list) or not data:
raise SystemExit("image API response did not contain data[0]")
first = data[0]
if not isinstance(first, dict) or not isinstance(first.get("b64_json"), str):
raise SystemExit("image API response did not contain data[0].b64_json")
output_image.parent.mkdir(parents=True, exist_ok=True)
output_image.write_bytes(base64.b64decode(first["b64_json"]))
def file_sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as file:
for chunk in iter(lambda: file.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def complete_job(job: dict[str, object], output_path: Path) -> None:
job["status"] = "complete"
job["source_path"] = str(output_path)
job["source_provenance"] = "secondary-fallback-image-api"
job["source_sha256"] = file_sha256(output_path)
job["output_sha256"] = file_sha256(output_path)View on GitHub (pinned to 5be4028344)
Solutions
- Inspect run_dir/raw/<job_id>.response.json to confirm whether data[0] carries url vs b64_json.
- Ensure the request asks for base64: the generations payload already sets output_format png, but if the model needs response_format=b64_json, add it to the payload/fields.
- Switch to a model that returns b64_json for the requested size.
- If only URLs are available, extend decode_response to download data[0]["url"] into output_image.
Example fix
// before
first = data[0]
if not isinstance(first, dict) or not isinstance(first.get("b64_json"), str):
raise SystemExit("image API response did not contain data[0].b64_json")
// after - fall back to url when b64_json is absent
first = data[0]
if not isinstance(first, dict):
raise SystemExit("image API response data[0] is not an object")
if isinstance(first.get("b64_json"), str):
output_image.write_bytes(base64.b64decode(first["b64_json"]))
elif isinstance(first.get("url"), str):
with urllib.request.urlopen(first["url"], timeout=300) as remote:
output_image.write_bytes(remote.read())
else:
raise SystemExit("image API response did not contain data[0].b64_json or url") Defensive patterns
Strategy: type-guard
Validate before calling
def extract_image_bytes(first_entry: object) -> bytes:
if not isinstance(first_entry, dict):
raise SystemExit("data[0] is not an object")
b64 = first_entry.get("b64_json")
if isinstance(b64, str):
return base64.b64decode(b64)
url = first_entry.get("url")
if isinstance(url, str):
with urllib.request.urlopen(url, timeout=300) as remote:
return remote.read()
raise SystemExit("data[0] has neither b64_json nor url") Type guard
def has_b64(entry: object) -> bool:
return isinstance(entry, dict) and isinstance(entry.get("b64_json"), str) Prevention
- Request b64 output explicitly in the API payload when the model supports response_format.
- Record a known-good response fixture and diff new responses against it during schema drift.
- If integrating an OpenAI-compatible proxy, confirm it returns b64_json before relying on it.
When it happens
Trigger: The images/generations or images/edits call succeeded but returned data[0] = {"url": "..."} (url format) instead of b64_json, or returned data[0] as a non-dict element, or b64_json was emitted as null/empty by the model.
Common situations: Default response_format for the model is url and the script did not request b64_json; using a third-party OpenAI-compatible image API that only returns URLs; a model variant that omits b64_json on certain sizes.
Related errors
- image API response did not contain data[0]
- grok image response had no data[0]
- grok image response missing b64_json/url
- nano-banana image non-JSON: ${truncate(text, 200)}
- nano-banana image response missing candidates[].content.part
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/21f044789beba90d.
Report an issue: GitHub.